PHP Tally Total from Entries in SQL - Best Practice Approach - php

not so much of a problem but more looking for best practice and the most efficient solution to an issue.
I have some code that reads all the lines for a userID in an sql table and can print them fine. Each row contains {Sales No. - D_No - Category1 - Category2 - Date}.
Now for each row I could have a massive number of if statements or etc to see if the category is equal to a field and then add 1 to a variable that acts as a tally as such. But I'm wanting something more efficient. Where it creates a variable of its own name and or adds to the existing variable of its name.
This is a summary of the pre-existing code:
while ($row = mysqli_fetch_assoc($result)) {
echo "<tr>";
foreach ($row as $field => $value) {
foreach ($salesItemsArray as $saleItem){
if (strpos($value, '******CategoryNAME******') !== false){
}
}
echo "<td>" . $value . "</td>"; // I just did not use "htmlspecialchars()" function.
}
echo "</tr>";
}
echo "</table>";
So this code would essentially (possibly with a bit of editing) work if i replace the *****CategoryNAME***** with the actual category and repeat for each category or use an equivilant switch command (if php has one?). However if i could get the program to create a variable called $category Name each time it sees a new category and then add 1 to it each other time it would work for any category name and would be much more efficient and simpler.
Is this possible and any ideas how to implement?
Willing to rephrase parts if needed if confusing.
updated attempt at code :
foreach ($row as $field => $value) { // I you want you can right this line like this: foreach($row as $value) {
foreach ($salesItemsArray as $saleItem){
if (strpos($value, $saleItem) !== false){
$foo[$saleItem] = $foo[$saleItem] + 1;
}
foreach ($foo as $saleTotal){
echo $saleTotal."<br/>".$foo[$saleTotal];
}
}
echo "<td>" . $value . "</td>";
Final code edit post hopefully
Thanks to comments i've gotten to this. However slight issue is it says there is 1 for every $foo[$saleItem] combination from echoing it out. As the database stands there should only be 1 item with 1 and everything else in the array and its variable 0...
while ($row = mysqli_fetch_assoc($individualResult)) {
echo "<tr>";
foreach ($row as $field => $value){
foreach ($salesItemsArray as $saleItem){
if (strpos($value, $saleItem) !== false){
if(isset($foo[$saleItem])) { $foo[$saleItem] += 1; } else { $foo[$saleItem] = 1;}
echo $saleItem;
}
foreach ($salesItemsArray as $saleTotal){
echo $foo[$saleTotal];
if ($foo[$saleTotal] > 0){
echo $saleItem."+".$foo[$saleTotal];
}
}
}
echo "<td>" . $value . "</td>";
echo "</tr>";
}

Related

Populate 2 column HTML table with a single PHP result set

Please forgive me as I am beginner in PHP.
I am trying to populate 2 two column table with inventory information. With my current code, I have the below image:
I would like to have two stores next to each other in this table. i.e Store Number 2 and Store Number 7 on the table row in the table, then Store 10 and 11 on the same row, and so on. Below is the code I am using so far to achieve this:
global $wpdb;
$result = $wpdb->get_results(
$wpdb->prepare( "
SELECT STORE_NAME,REPLACE(STORE_NAME, ' ', '-') as STOREURL, INVENTORY, STORE_NUMBER FROM StoreInventory
WHERE SKU = %s",
$product_sku
)
);
if ($result){
echo '<table class=\'inventory\'>';
foreach($result as $row) {
echo '<tr><td><div><a href=\'https://mystore.com/stores/'. $row->STOREURL . '\' target=\'_parent\'>Store Number: ' . $row->STORE_NUMBER . '</a><br/>' .$row->INVENTORY. ' on hand. </div></td></tr>';
}
echo '</table>';
} else {
echo '<table class=\'nostock\'><td>This item is out of stock, check back later for updated information!</td></table>';
}
The problem I am having is that I am looping through the record set row by row, and adding the data to each row. I have attempted to have a loop inside a loop, which will not give me the correct results.
Is it possible to split the result set into two multi-dimensional arrays and loop through each one separately then add them to the table? Can I call out a specific row with a counter within the loop?
Any advise or direction would be a great help.
A relatively simple approach would be to create a dummy variable to store the column. EX:
$column_number = 0;
echo '<table class=\'inventory\'><tr>';
foreach($result as $row) {
echo '<td><div><a href=\'https://mystore.com/stores/'. $row->STOREURL . '\' target=\'_parent\'>Store Number: ' . $row->STORE_NUMBER . '</a><br/>' .$row->INVENTORY. ' on hand. </div></td>';
$column_number += 1;
if ($column_number == 2) {
echo '</tr><tr>';
$column_number = 0;
}
}
echo '</tr></table>';
Final answer based on ARubiksCube's answer:
if ($result){
$column_number = 0;
echo '<table class=\'inventory\'><tr>';
foreach($result as $row) {
echo '<td \' width=\'50%\' ><div><a href=\'https://shopliquornl.com/stores/'. $row->STOREURL . '\' target=\'_parent\'>' . $row->STORE_NAME . '</a><br/>' .$row->INVENTORY. ' on hand</div></td>';
$column_number += 1;
if ($column_number == 2) {
echo '</tr><tr>';
$column_number = 0;
}
}
echo '</table>';
} else {
echo '<table class=\'nostock\'><td>This item is out of stock, check back later for updated information!</td></table>';
}

How to do an inner loop of records in php

I am learning PHP and I want to know how to do an inner loop or nested loop with records in PHP. I will appreciate if somebody explains me how to do this type of loop in PHP.
I have this table in MySQL
[]
I just want to create a report table in PHP that looks like this:
So far, I know how to do a current loop with the code below but how could I do in the same loop and inner loop to show dishes like table above. I know how to create the format (table, spaces, etc) I just need the PHP logic to do this in the best way.
<?php
do { ?>
Table in here
<?php } while ($selecc = mysqli_fetch_assoc($conmenu)); ?>
The clean/direct approach should be something like this:
SELECT Client, Option, GROUP_CONCAT(Dish SEPARATOR ', ')
FROM table_name
GROUP BY Client, Option
Then with your data already grouped and glued together, just print your strings in a single loop of the result set.
Using a do {} while () is of no benefit here.
Here's an untested snippet...
if ($conmenu) {
echo '<table>';
echo '<tr><td>Client</td><td>Option</td><td>Dishes</td></tr>';
while ($row = mysqli_fetch_assoc($conmenu)) {
echo '<tr><td>' , implode('</td><td>', $row) , '</td></tr>';
}
echo '</table>';
}
For the record:
The maximum permitted result length in bytes for the GROUP_CONCAT() function. The default is 1024.
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_group_concat_max_len
Also, $conmenu is iterable, so you could use a foreach instead of a while loop.
foreach ($conmenu as $row) { ...
If you want to do it the hard way...
SELECT Client, Option, Dish
FROM table_name
ORDER BY Client, Option
Then... (untested)
if ($conmenu) {
echo '<table>';
echo '<tr><td>Client</td><td>Option</td><td>Dishes</td></tr>';
$group = null;
foreach ($conmenu as $row) {
if ($group !== $row['Client'] . '_' . $row['Option']) {
if ($group !== null) {
echo '</td></tr>';
}
echo '<tr><td>' , implode('</td><td>', $row);
} else {
echo ", " , $row['Dish'];
}
$group = $row['Client'] . '_' . $row['Option']; // update group
}
echo '</td></tr>'; // close final iteration
echo '</table>';
}

fetching data and trying to create a loop to determine lowest value

This is going to be a newbie question, so bear with me.
I have a database in which I fetch the data, I would like to create a for loop which will loop through the fetched data and will determine what the lowest time is. This is how my loop looks like: (take into consideration I only took the part out that seemed usefull to post, and $row['timePV'] is a time based value such as: 23:00)
$arrayCount = array();
while ($row = mysqli_fetch_assoc($result)) {
echo "<tr>";
echo "<td>";
echo $row['timePV'];
echo "</td>";
echo "</tr>";
array_push($arrayCount,$row['timePV']);
}
echo "</table>";
}
$c = 100000;
for ($i = 0; $i < sizeof($arrayCount); $i++) {
$arrayCount[$i];
if ($arrayCount[$i] < $c) {
$c = $arrayCount[$i];
echo $c;
} else {
//do something else
}
}
So what I want to achieve: Loop through the stored data and take out the lowest value and display that value, but it only displays all the values.
So my question: How can I make the loop in such way that it will take the lowest value and display it to me?
You don't have to do another loop to calculate lowesttime. You can do it in that while loop with checking previous and present timePv like following
//$timeExample=[["timePV"=>"11:30"],["timePV"=>"11:20"],["timePV"=>"13:30"]];//example of data
$lowestTime = null;//Deault defined it null
while ($row = mysqli_fetch_assoc($result)) {
//foreach($timeExample as $row){ //foreach for run example
if($lowestTime){
$lowestTime=min($lowestTime,strtotime($row['timePV']));//If not null we also get min lowerstTime from previous //and current one
}else{
$lowestTime=strtotime($row['timePV']);//It will work for only first iteration since $lowestTime will null in //first iteration
}
echo "<tr>";
echo "<td>";
echo $row['timePV'];
echo "</td>";
echo "</tr>";
}
echo date("h:i",$lowestTime);//11:20 example out

PHP: Creating big HTML-table efficiently

I'm making a HTML table based on certain information in my MySQL database. The tables I need from the database hold the data for rows (rowid, rowname), columns (columnid, columnname) and cell data. A table, that links IDs from rows and columns together (cellid, rowid, columnid, somedata).
The table looks something like this:
__________| column1 | column2 | column3 | ...
row1 | somedata | somedata | |
----------|----------|----------|----------|-----
row2 | somedata | | somedata |
----------|----------|----------|----------|-----
... | | | |
My approach was to use several nested foreach loops, something like this:
$rows = new Rows(); //These objects are containers for objects
$columns = new Columns(); //that hold some of the database data.
$alldata = new Alldata(); //MySQL queries within these objects are irrelevant, I think. They already get the relevant data
$count = count($alldata);
echo "<table>";
echo "<tr>";
echo "<td> </td>";
foreach ($columns->getColumns() as $column) {
echo "<td>".$column->getColumnname()."</td>";
}
echo "</tr>";
foreach ($rows->getRows() as $row) {
echo "<tr>";
echo "<td>".$row->getRowname()."</td>";
foreach ($columns->getColumns() as $column) {
$last = 1;
foreach ($alldata->getAlldata() as $data) {
if ($data->getCID() == $column->getID() & $data->getRID() == $row->getID()) { //If the column has data the related to the row
echo "<td>".$data->getSomedata()."</td>";
break;
}
if ($last == $count) { //if loop couldn't find any entries, it prints an empty cell
echo "<td> <td>";
}
$last++
}
}
echo "</tr>";
}
echo "</table>";
Bruteforcing, obviously this is not very efficient method when there are several hundred rows of data on any table in the database and I don't like this. Any ideas how to make this more efficient? Is there better way of creating a table like I need?
EDIT:
Pondering about this problem for a week has finally given me some answers. It was so simple!
I did a slight modification to my Column object class. Previously, my code went through all possible entries on celldata table in the database. Now Column object gets an array of celldata where columnid's match and I can do the comparison using only that data.
$rows = new Rows();
$columns = new Columns();
echo "<table>";
echo "<tr>";
echo "<td> </td>";
foreach ($columns->getColumns() as $column) {
echo "<td>".$column->getColumnname()."</td>";
}
echo "</tr>";
foreach ($rows->getRows() as $row) {
echo "<tr>";
echo "<td>".$row->getRowname()."</td>";
foreach ($columns->getColumns() as $column) {
$last = 1;
$count = count($column->getAlldata());
foreach ($column->getAlldata() as $data) {
if ($data->getCID() == $column->getID() & $data->getRID() == $row->getID()) {
echo "<td>".$data->getSomedata()."</td>";
break;
}
if ($last == $count) {
echo "<td> <td>";
}
$last++
}
}
echo "</tr>";
}
echo "</table>";
Much faster, although still bruteforcing but there's less amount of data to go through. Of course, now the problem is that Column objects may do quite a lot of MySQL queries, depending on how many Columns there are.
If you ensure that the data fetched from MySQL is correctly ordered in $alldata by joining the tables and specifying an ORDER BY clause in your query:
SELECT data.*
FROM data RIGHT JOIN rows USING (rowid) RIGHT JOIN columns USING (columnid)
ORDER BY rowname, columnname;
Then you only need to output each cell in order:
echo '<table>';
echo '<thead>'
echo '<tr>';
echo '<th> </th>';
foreach ($columns->getColumns() as $column) {
echo '<th scope="col">', htmlentities($column->getColumnname()), '</th>';
}
echo '</tr>';
echo '</thead>';
echo '<tbody>';
$data = $alldata->getAlldata();
foreach ($rows->getRows() as $row) {
echo '<tr>';
echo '<th scope="row">', htmlentities($row->getRowname()), '</th>';
foreach ($columns->getColumns() as $column) {
$d = each($data);
echo '<td>', ($d ? htmlentities($d[1]->getSomedata()) : ' '), '</td>';
}
echo '</tr>';
}
echo '</tbody>';
echo '</table>';
The best way to solve this would be to rewrite the query for $alldata so that it is in the order you want like eggyal suggested. If you can't do that for some reason, you could iterate through $alldata in the beginning and create a properly indexed array from it. Something like this:
$ordereddata = array();
foreach($alldata as $d) {
$ordereddata[$d->getCID()][$d->getRID()] = $d->getSomedata();
}
Now you can replace your foreach($alldata) loop with this:
if(isset($ordereddata[$column->getID()][$row->getID()])) {
echo "<td>{$ordereddata[$column->getID()][$row->getID()]}</td>";
} else {
echo "<td> </td>";
}

Breaking up a long line of values in a box

The array $carry_over returns a really long list of entries, too long for my printout page. I would love to make it in such a way that after 4 entries, it breaks and goes to the next line and breaks at the next four entries until all entries are in.
How can i do this?
Thanks
echo "<table class=\"altrowstable\" bgcolor = gold >\n";
$count = 0;
echo "<tr align= \"center\">\n";
$carry_over = array();
$score_count = mysql_numrows($query8);
echo "<td>"."Failed: ";
if($score_count !== 0){
while ($row8 = mysql_fetch_assoc($query8)) {
echo "<th>".$row8['course_code']."</th>";
if ( $count == 7 ){
echo "</tr>\n";
echo "</table>";
}
}
}
Update : Now only the first 7 entries are covered inside the table tags, the subsequent ones are outside the table tags. How can i put them in the tabke tags?
Thanks
Not sure if this is what you are looking for, but you could try:
$count = 0;
echo "<tr>";
while ($row8 = mysql_fetch_assoc($query8)) {
echo "<th>" . $row8['course_code'] . "</th>";
$count++;
if(count == 4) {
echo "</tr><tr>";
$count = 0;
}
}
echo "</tr>";
It looks like you're using a table for list data. Instead of using a <table>, you should be using a <ul> with <li> for each element. This can then be styled so that each li has display: inline-block;, for example.
I cannot tell what the table looks like from the code above, but you can put an iterator in to count to four then wrap. You also may want to check out Wordwrap

Categories