I'm just learing to use php, and I've been working on this code that is not very efficient because it is very long and I would like it to be more automated. The idea is to generate a table with 2 colums, one with the user name and the other with the score of each user. As you may imagine, the score is based on a function that use other variables of the same user. My goal is to only have to set one variable for each user and a new row is would be created automatically at the end of the table.
<?php
$array1['AAA'] = "aaa"; ## I'm suposed to only set the values for array1, the rest
$array1['BBB'] = "bbb"; ## should be automatic
$array1['ETC'] = "etc";
function getscore($array1){
## some code
return $score;
};
$score['AAA'] = getscore($array1['AAA']);
$score['BBB'] = getscore($array1['BBB']);
$score['ETC'] = getscore($array1['ETC']);
?>
<-- Here comes the HTML table --->
<html>
<body>
<table>
<thead>
<tr>
<th>User</th>
<th>Score</th>
</tr>
</thead>
<tbody>
<tr>
<td>AAA</td> <-- user name should be set automaticlly too -->
<td><?php echo $score['AAA'] ?></td>
</tr>
<tr>
<td>BBB</td>
<td><?php echo $score['BBB'] ?></td>
</tr>
<tr>
<td>ETC</td>
<td><?php echo $winrate['ETC'] ?></td>
</tr>
</tbody>
</table>
</body>
</html>
Any help would be welcome!
$outputHtml = ''
foreach( $array1 as $key => $val )
{
$outputHtml .= "<tr> ";
$outputHtml .= " <td>$key</td>";
$outputHtml .= " <td>".getscore($array1[$key]);."</td>";
$outputHtml .= " </tr>";
}
then in $outputHtml will be html content with all rows you wanna display
This is a little cleaner, using foreach and printf:
<?php
$array1 = array(
['AAA'] => "aaa",
['BBB'] => "bbb",
['ETC'] => "etc"
);
function getscore($foo) {
## some code
$score = rand(1,100); // for example
return $score;
};
foreach ($array1 as $key => $value) {
$score[$key] = getscore($array1[$key]);
}
$fmt='<tr>
<td>%s</td>
<td>%s</td>
</tr>';
?>
<-- Here comes the HTML table --->
<html>
<body>
<table><thead>
<tr>
<th>User</th>
<th>Score</th>
</tr></thead><tbody><?php
foreach ($array1 as $key => $value) {
printf($fmt, $key, $score[$key]);
}
?>
</tbody></table>
</body>
</html>
Also, I'll just note that you don't seem to be using the values of $array1 anywhere. Also,
I'm not sure what $winrate is in your code, so I ignored it.
Related
I have this async code , but when i try to render inside a table , the table become a mess (image) but after a page refresh the table is perfctly fine and i dont know why , how can i fix this problem ?
and if is possible to have a better async code , i know i need to async the
$api->getMatchTimeline($match->gameId); but i don't know how can i do it.
<table class="table table table-bordered" style="width:100%">
<tr>
<thead>
<th>Items</th>
</thead>
</tr>
<tbody>
<?php
$onSuccess = function (Objects\MatchDto $match) use (&$api, $champ) {
echo "<tr>";
echo "<td>";
foreach ($match->participants as $partId) {
if ($partId->championId == $champ) {
$participant_id = $partId->stats->participantId;
$pp = $api->getMatchTimeline($match->gameId);
foreach ($pp->frames as $p) {
foreach ($p->events as $t) {
if ($t->type == "ITEM_PURCHASED" and $t->participantId == $participant_id) {
$item_id = $t->itemId;
$d = $api->getStaticItem($item_id);
$depth = $d->depth;
if (($depth == 3 or $depth == 2)) {
echo "<a href = https://lolprofile.net/match/kr/$match->gameId#Match%20History >";
echo "<img src =" . DataDragonAPI::getItemIconUrl($item_id) . " />" . '</a>';
}
}
}
}
}
}
echo "</td>";
echo "</tr>";
};
$onFailure = function ($ex) {
echo $ex;
};
foreach ($database as $game) {
$api->nextAsync($onSuccess);
$match = $api->getMatch($game->match_ids);
}
$api->commitAsync();
?>
</tbody>
</table>
render outside the table
The problem isn't to do with your "async" PHP code, but because your <table> markup is incorrect.
HTML's <table> element has two different forms. The first is the "implicit <tbody> form, like this:
<table>
<tr>
<td>col 1</td>
<td>col 2</td>
<td>col 3</td>
</tr>
</table>
The other has an explicit <tbody> element, which can also optionally have a <thead> and <tfoot> (you can also have multiple <tbody> but only a single <thead>. You can use a <thead> and <tfoot> with an implicit <tbody> but this is not recommended - I recommend everyone use the explicit syntax, like so:
<table>
<tbody>
<tr>
<td>col 1</td>
<td>col 2</td>
<td>col 3</td>
</tr>
</tbody>
</table>
Note that the actual DOM representation of both tables is the same: in the DOM a <table> never has <tr> as immediate children.
Secondarily, you can also make your code a LOT easier to read and follow if you separate your application logic from your rendering logic by doing all of your API calls and whatnot at the start of your PHP script and populate a "view model" object and then the rendering logic is greatly simplfied, like so:
<?php
// This PHP block should be before *any* HTML is written:
class MatchAndItems {
public Objects\MatchDto $match;
public Array $items;
}
$allMatches = Array(); # Array of `MatchAndItems`.
$onFailure = function ($ex) {
echo $ex;
};
$gotMatch = function (Objects\MatchDto $match) use (&$api, $champ, $allMatches) {
$e = new MatchAndItems();
$e->match = $match;
$e->items = array();
foreach ($match->participants as $partId) {
if ($partId->championId == $champ) {
$participant_id = $partId->stats->participantId;
$pp = $api->getMatchTimeline($match->gameId);
foreach ($pp->frames as $p) {
foreach ($p->events as $t) {
if ($t->type == "ITEM_PURCHASED" and $t->participantId == $participant_id) {
$item_id = $t->itemId;
$d = $api->getStaticItem($item_id);
array_push( $e->items, $d );
}
}
}
}
}
array_push( $allMatches, $e );
};
# Set-up web-service HTTP request batches:
foreach( $database as $game ) {
$api->nextAsync( $gotMatch )->getMatch( $game->match_ids );
}
# Invoke the batch:
$api->commitAsync();
# The below code uses https://www.php.net/manual/en/control-structures.alternative-syntax.php
?>
<!-- etc -->
<table class="table table table-bordered" style="width: 100%">
<thead>
<tr>
<th>Items</th>
</tr>
</thead>
<tbody>
<?php foreach( $allMatches as $match ): ?>
<tr>
<td>
<?php
foreach( $match->items as $item ):
if( $item->depth == 2 or $item->depth == 3 ):
echo "<a href = https://lolprofile.net/match/kr/$match->gameId#Match%20History >";
echo "<img src =" . DataDragonAPI::getItemIconUrl($item_id) . " />" . '</a>';
endif;
endforeach;
?>
</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
I am just learning PHP ,and I want to create a table that display echo data that I submit to my database , the problem I have that the table displayed horizontally by default as you see Horizontal default table this my script
<table >
<tr>
<th>Name</th>
<th>Age</th>
<th>Height</th>
</tr>
<?php
$conn = mysqli_connect("localhost", "root", "", "class");
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT Name, Age, Height FROM student order by Name desc";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "<tr><td>" . $row["Name"]. "</td><td>" . $row["Age"] . "</td><td>"
. $row["Height"]. "</td></tr>";
}
echo "</table>";
} else //{ echo "0 results"; }//
$conn->close();
?>
</table>
but I want it to be echoed vertically instead like this VERTICAL RESULT I WANT and I tried to change html in echo in my PHP code but I can't get the result at all and the shape of the table is far away from what I want and this is the full script of my page .
Like everyone else said, you should convert your horizontal array into a vertical one.
Of course it should be a universal function to convert any query result, as opposed to hardcoding the row headings. The idea is to get each row's array keys and use them as the keys for the new array and then add each corresponding value to the new array item.
Here is how it's done in mysqli:
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = mysqli_connect('127.0.0.1','root','','test');
$mysqli->query("set names 'UTF8'");
$data = [];
$res = $mysqli->query("SELECT Name, Age, Height FROM student order by Name desc");
while ($row = $res->fetch_assoc()) {
foreach(array_keys($row) as $key) {
$data[$key][] = $row[$key];
}
}
and then you get an array with desired structure which you can output using the code from ROOT's answer:
<table border="1">
<?php foreach($data as $key => $val): ?>
<tr>
<td><?= $key ?></td>
<?php foreach($val as $field): ?>
<td><?= $field ?></td>
<?php endforeach ?>
</tr>
<?php endforeach ?>
</table>
I mocked your data into normal array, I used a while loop to create a new Array and create the format that we need to be able to flip the columns into rows, here is what I think you want:
<?php
$users = [
[
'name'=> 'James',
'height'=> 1.75,
'age'=> 18,
],
[
'name'=> 'Bill',
'height'=> 170,
'age'=> 16,
]
];
$newArr = [];
foreach($users as $key => $val) {
$newArr['name'][$i] = $val['name'];
$newArr['age'][$i] = $val['age'];
$newArr['height'][$i] = $val['height'];
$i++;
}
?>
<table border="1">
<?php foreach($newArr as $key => $val): ?>
<tr>
<td><?php echo $key; ?></td>
<?php foreach($val as $field): ?>
<td><?php echo $field; ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach ?>
</table>
It's not a good idea ! if you have a lot of ROW you will generate a long table not visible for user in screen.
if you want to do it after all you can change table structure but you will not respect html table structure.
I will give you a
Dirty code
<table>
<tr>
<th>Name</th>
<?php foreach ($row as $value) { ?><td><?php echo$value["Name"]; ?></td>
<?php } ?>
</tr>
<tr>
<th>Age</th>
<?php foreach ($row as $value) { ?>
<td><?php echo $value["Age"]; ?></td>
<?php } ?>
</tr>
<tr>
<th>Height</th>
<?php foreach ($row as $value) { ?>
<td><?php echo $value["Height"]; ?></td>
<?php } ?>
</tr>
</table>
I recommand to USE CSS instead a table
I am having a problem to convert my $quantity_total which is as example (113) from 3 different products.
I want it to be in a table like below.
I have been trying to use chunk_split and explode but if i was able to succeed in that. I wouldn't be able to make it dynamic.
<table>
<tr>
<th>Quantity</th>
</tr>
<tr>
<td>1</td>
</tr>
<tr>
<td>1</td>
</tr>
<tr>
<td>3</td>
</tr>
</table>
$total=0;
$item_count=0;
$arr = array();
$quantity_all = '';
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
extract($row);
$arr[] = $row;
$_SESSION['cart-checkout'] = $arr;
$quantity=$_SESSION['cart'][$id]['quantity'];
$quantity_all .=$quantity;
$sub_total=$price*$quantity;
echo "<div class='cart-row'>";
echo "<div class='col-md-8'>";
echo "<div class='product-name m-b-10px'><h4>{$name}</h4></div>";
echo $quantity>1 ? "<div>{$quantity} items</div>" : "<div>{$quantity} item</div>";
echo "</div>";
echo "<div class='col-md-4'>";
echo "<h4>$" . number_format($price, 2, '.', ',') . "</h4>";
echo "</div>";
echo "</div>";
$item_count += $quantity;
$total+=$sub_total;
$_SESSION['total'] = $total;
$_SESSION['item-count'] = $item_count;
}
$_SESSION['quantity-all'] = $quantity_all;
Is this possible? And i need it to be dynamic. So if it were 10 different quantities. It would make 10 table rows.
I hope someone can help me, would really appreciate it a lot! It's the last thing to finish my e-commerce webshop.
As mentioned in my comment, I don't think this is good solution... but the function you're looking for is str_split. https://stackoverflow.com/a/9814389/296555
http://sandbox.onlinephpfunctions.com/code/0bbee53cafafc0d5e8954e07d0abc2c86c6c89a8
<?php
$rows = '156165165489465131';
echo '<table>';
echo '<tr><th>Quantity</th></tr>';
foreach (str_split($rows) as $row) {
echo "<tr><td>$row</td></tr>";
}
echo '</table>';
I dont know if this Is what you want, but you can try something like:
<table>
<tr>
<td>Quantity</td>
</tr>
<?php
$characters = str_split( (string) $quantity_total);
foreach($characters as $char){
echo "
<tr>
<td> $char </td>
</tr>
";
}
?>
</table>
I have simulated the mysql result from an old SO question as the following array:
<?php
$arr = array(
array(
'title'=>'Test',
'name'=>'ABC',
'cat_desc'=>'ABC_DESC',
'parent'=>0,
'parent_menu'=>1
),
array(
'title'=>'Test2',
'name'=>'DEF',
'cat_desc'=>'DEF_DESC',
'parent'=>0,
'parent_menu'=>2
),
array(
'title'=>'Test2',
'name'=>'GHI',
'cat_desc'=>'GHI_DESC',
'parent'=>1,
'parent_menu'=>0
),
array(
'title'=>null,
'name'=>'JKL',
'cat_desc'=>'JKL_DESC',
'parent'=>2,
'parent_menu'=>0
)
);
//print_r($arr);
?>
Now I wonder if I could print the result in this format:
<table>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<tr>
<td> Menu Title Test </td>
<td> Main Category ABC</td>
</tr>
<tr>
<td>GHI</td>
<td>GHI_DESC</td>
</tr>
<tr>
<td> Menu Title Test2 </td>
<td> Main Category DEF</td>
</tr>
<tr>
<td>JKL</td>
<td>JKL_DESC</td>
</tr>
</table>
I am trying the following php to print but it could not give the expected result:
<table>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<?php
$r = 0;
while(list($key, $val)=each($arr)) {
if($val['parent']==0):
if($r % 1==0): ?>
<tr>
<td> Menu Title <?php echo $val['title'];?> </td>
<td> Main Category <?php echo $val['name'];?></td>
</tr>
<?php endif;
endif;
if($val['parent']!=0){ ?>
<tr>
<td><?php echo $val['name'];?></td>
<td><?php echo $val['cat_desc'];?></td>
</tr>
<?php
}
$r++;
} ?>
</table>
Your help and suggestion is very much welcome.
I find it difficult to figure out what you exactly want from your array structure. But I noticed that array element 0 is paired with element 2, and element 1 is paired with element 3. Therefore my code would be like following. It will give you exactly the table that you wanted.
print "<table border=1>";
$numArray = count($arr) / 2;
for($i=0;$i<$numArray;$i++) {
$element = $arr[$i];
print "<tr><td>Menu Title {$element['title']}</td><td>Main Category {$element['name']}</td></tr>";
$element = $arr[$i+2];
print "<tr><td>{$element['name']}</td><td>{$element['cat_desc']} </td></tr>";
}
print "</table>";
You can use this where I commented what to do and why
<table>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<?php
// Store the array into temporary array
$temp_array = $arr;
foreach ($arr as $akey => $sArr)
{
// Check that prrent is 0
if ( $sArr['parent'] ==0 )
{
// Store parent_menu id
$parent_menu = $sArr['parent_menu'];
?>
<tr>
<td> Menu Title <?php echo $sArr['title'];?> </td>
<td> Main Category <?php echo $sArr['name'];?></td>
</tr>
<?php
// Unset or remove current index from array
unset($temp_array[$akey]);
// Iterate all rows
foreach ($temp_array as $skey => $aval)
{
// Check that it has parent for the current menu
if ( $aval['parent'] == $parent_menu )
{
?>
<tr>
<td><?php echo $aval['name'];?></td>
<td><?php echo $aval['cat_desc'];?></td>
</tr>
<?php
}
}
// End of foreach
}
// End of if
}
// End of foreach
?>
</table>
I find that data from a relational DB doesn't really lend itself to direct use and requires some massaging to lower the code complexity. So, if your aim is to make a dynamic menu with submenus, I would suggest refactoring the data structure into more of a tree structure and then looping over each level.
A better data structure would be:
$menus = array(
1 => array( // original array item index 0
'title'=>'Test',
'name'=>'ABC',
'cat_desc'=>'ABC_DESC',
'parent'=>0,
'parent_menu'=>1
'children'=> array( // new array containing submenus
array( // original array item index 2
'title'=>'Test2',
'name'=>'GHI',
'cat_desc'=>'GHI_DESC',
'parent'=>1,
'parent_menu'=>0
),
),
),
2 => array( // original array item index 1
'title'=>'Test2',
'name'=>'DEF',
'cat_desc'=>'DEF_DESC',
'parent'=>0,
'parent_menu'=>2
'children'=> array( // array containing original item index 2
array(
'title'=>null,
'name'=>'JKL',
'cat_desc'=>'JKL_DESC',
'parent'=>2,
'parent_menu'=>0
),
),
),
);
Rather than just entering the data in this more covenient form, it is good practice to convert it. So, to get from the original data to this structure you can use a simple single pass foreach loop:
$menus = [];
foreach($arr as $item) {
if($item['parent'] == 0) {
$item['children'] = array();
$menus[$item['parent_menu']] = $item;
}
else {
$menus[$item['parent']]['children'][] = $item;
}
}
Once you have the data in a nice convenient form you can use simple nested foreach loops to iterate it and output the table in a clear manner like this:
<table>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<?php foreach($menus as $menu) { ?>
<tr>
<td> Menu Title <?php echo $menu['title'];?> </td>
<td> Main Category <?php echo $menu['name'];?></td>
</tr>
<?php foreach($menu['children'] as $child) { ?>
<tr>
<td><?php echo $child['name'];?></td>
<td><?php echo $child['cat_desc'];?></td>
</tr>
<?php } } ?>
</table>
From what I see, I believe $r % 2 makes a little more sense than $r % 1
In case $r is an integer, $r % 1 will always return a zero. Looks like in your case you use this to split logic for odd and even numbers, which makes sense for your data set.
Make sure the data set doesn't change. Maybe it'd be better use a more reliable approach. Adding indexes to the data set wouldn't harm either :)
I want to implement a logic for creating a three column table using foreach loop. A sample code will look like this.
$array = ['0','1','2','3','4','5','6'];
$table = '<table class="table"><tbody>';
foreach($array as $a=>$v){
//if 0th or 3rd???????????wht should be here?
$table .= '<tr>';
$table .= '<td>$v</td>';
//if 2nd or 5th??????????and here too???
$table .= '</tr>';
}
$table = '</tbody></table>';
Any ideas?
Expected output is a simple 3X3 table with the values from the array
Use this you may looking for this
<?php
echo('<table><tr>');
$i = 0;
foreach( $array as $product )
{
$i++;
echo '<td>'.$product .'</td>';
if($i % 3==0)
{
echo '</tr><tr>';
}
}
echo'</tr></table>';
?>
Result Here:
<table>
<tr>
<td>data1</td>
<td>data2</td>
<td>data3</td>
</tr>
<tr>
<td>data4</td>
<td>data5</td>
<td>data6</td>
</tr>
</table>
This should work for you:
(See that I added a tr at the start and end before and after the foreach loop. Also I changed the quotes to double quotes and made sure you append the text everywhere.)
<?php
$array = ['0','1','2','3','4','5','6'];
$table = "<table class='table'><tbody><tr>";
//^^^^ See here the start of the first row
foreach($array as $a => $v) {
$table .= "<td>$v</td>";
//^ ^ double quotes for the variables
if(($a+1) % 3 == 0)
$table .= "</tr><tr>";
}
$table .= "</tr></tbody></table>";
//^ ^^^^^ end the row
//| append the text and don't overwrite it at the end
echo $table;
?>
output:
<table class='table'>
<tbody>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td>6</td>
</tr>
</tbody>
</table>
Here is an easy solution with array_chunk():
<?php
$array = array('0','1','2','3','4','5','6');
$d = array_chunk($array, 3);
$table = "<table border='1' class='table'><tbody>";
foreach($d as $v)
$table .= "<tr><td>" . implode("</td><td>", $v) . "</td></tr>";
$table .= "</tbody></table>";
echo $table;
?>
Here is an easy solution with incrementing that works with a dynamically generated table like the one in Magento product view page to help display product attributes in two table columns preceded by attribute label -> practically we have 4 table columns together with attribute labels. This is useful for products with multiple attributes that take a long page to display.
<?php
$_helper = $this->helper('catalog/output');
$_product = $this->getProduct();
if($_additional = $this->getAdditionalData()): ?>
<h2><?php echo $this->__('Additional Information') ?></h2>
<table class="table table-bordered table-hover" id="product-attribute-specs-table">
<col width="25%" />
<col />
<tbody>
<?php $i = 1; ?>
<tr>
<?php foreach ($_additional as $_data): ?>
<?php $_attribute = $_product->getResource()->getAttribute($_data['code']);
if (!is_null($_product->getData($_attribute->getAttributeCode())) && ((string)$_attribute->getFrontend()->getValue($_product) != '')) { ?>
<th style="width: 20%;"><?php echo $this->htmlEscape($this->__($_data['label'])) ?></th>
<td class="data" style="width:20%;"><?php echo $_helper->productAttribute($_product, $_data['value'], $_data['code']) ?></td>
<?php $i++; if($i > 1 && ($i & 1) ) echo "</tr><tr>";?>
<?php } ?>
<?php endforeach; ?>
</tr>
</tbody>
</table>
<script type="text/javascript">decorateTable('product-attribute-specs-table')</script>