Print results of a SELECT query as preformatted text in PHP? - php

I'm looking for an easy and quick way to print out the results of a MySQL SELECT query in PHP as preformatted text. What I would like is to be able to pass a query object to a function and get a printout of the recordset like the command line MySQL client does when running SELECT statements.
Here is an example of how I want it to look (i.e. ASCII):
+----+-------------+
| id | countryCode |
+----+-------------+
| 1 | ES |
| 2 | AN |
| 3 | AF |
| 4 | AX |
| 5 | AL |
| 6 | DZ |
| 7 | AS |
| 8 | AD |
| 9 | AO |
| 10 | AI |
+----+-------------+
It's basically for a generic import script, I am doing a SELECT query and want to display the results to the user for confirmation.

sprintf is your friend, if you must have a non-HTML fixed width output.
ETA:
//id: integer, max width 10
//code: string max width 2
$divider=sprintf("+%-10s+%-13s+",'-','-');
$lines[]=$divider;
$lines[]=sprintf("|%10s|%13s|",'id','countryCode'); //header
$lines[]=$divider;
while($line=$records->fetch_assoc()) {
//store the formatted output
$lines[]=sprintf("| %10u | %2.2s |", $line['id'],$line['code']);
}
$table=implode("\n",$lines);
echo $table;
If you want to print out immediately instead of storing the results, use printf instead- same syntax. There is a reasonable PHP (s)printf tutorial here.

function formatResults($cols, $rows) {
echo'<table>';
echo '<tr>';
foreach ($cols as $v) {
echo '<th>' . $v['field'] . '</th>';
}
echo '</tr>';
foreach ($rows as $sRow) {
echo '<tr>';
foreach ($sRow as $v) {
echo "<td>$v</td>";
}
echo '</tr>';
}
echo '</table>';
}
$qry = $pdo->query('DESCRIBE table');
$cols = $qry->fetchAll(PDO::FETCH_ASSOC);
$pdo->query('SELECT * FROM table');
$rows = $qry->fetchAll(PDO::FETCH_ASSOC);
formatResults($cols, $rows);
Untested but should work.
Edit: Missed ['field'] index ;)

Related

Remove repeating data in a column

I am currently developing an ordering system where a customer can order many items. I also have an admin where he/she can see all the orders on that day. The Admin can view the name of the customer, the total payable, the products and the quantity of the product the customer have ordered.
I am currently seeing this results using my query.
Name | Payable | Product | Quantity
Test | 165 | keychain | 3
Test | 165 | Tumbler | 1
Miguel | 525 | Keychain | 3
Miguel | 525 | Magic Mug | 3
Dandel | 1010 | keychain | 3
Dandel | 1010 | T-shirt | 2
Dandel | 1010 | Keychain | 3
Dandel | 1010 | Mug | 5
This is my query.
$result = mysql_query("
SELECT reservation.firstname, reservation.lastname, reservation.payable, reservation.city, orders.product, orders.qty, reservation.date
FROM orders
INNER JOIN reservation
ON orders.confirmation = reservation.confirmation
WHERE reservation.date = CURDATE() && reservation.city = '24th Floor'
");
while($row = mysql_fetch_array($result))
{
echo '<tr>';
echo '<td style="border: 1px solid black;">'.$row['firstname'].'</td>';
echo '<td>'.$row['payable'].'</td>';
echo '<td>'.$row['product'].'</td>';
echo '<td>'.$row['qty'].'</td>';
echo '</tr>';
}
I want to get results like this. How can I do it?
Name | Payable | Product | Quantity
Test | 165 | keychain | 3
| | Tumbler | 1
Miguel | 525 | Keychain | 3
| | Magic Mug | 3
Dandel | 1010 | keychain | 3
| | T-shirt | 2
| | Keychain | 3
| | Mug | 5
You can maintain some state while iterating which keeps track of whether the current row is a new name/payable:
$last_name_seen = NULL;
while ($row = mysql_fetch_array($result)) {
$firstname = "";
$payable = "";
if ($last_name_seen === NULL || $row['firstname'] != $last_name_seen) {
$last_name_seen = $row['firstname'];
$firstname = $row['firstname'];
$payable = $row['payable'];
}
echo '<tr>';
echo '<td style="border: 1px solid black;">'.$firstname.'</td>';
echo '<td>'.$payable.'</td>';
echo '<td>'.$row['product'].'</td>';
echo '<td>'.$row['qty'].'</td>';
echo '</tr>';
}
Note that your MySQL query should have some ORDER BY clause, to generate the ordering you want, e.g.
ORDER BY Name, Product;
As the comments above also suggest, if you are using a deprecated PHP API, you should consider upgrading to something more modern. But, the logic used in the above loop would not change much with changing the MySQL API.
You have to set flag for name & payable column & use array_column(),array_unique() to get unique column values :
<?php
$result = array(array("Name"=>"Test","Payable"=>'165',"Product"=>"keychain","Quantity"=>3),array("Name"=>"Test","Payable"=>'165',"Product"=>"Tumbler","Quantity"=>1));
$name_arr = array_unique(array_column($result, 'Name'));
$payable_arr = array_unique(array_column($result, 'Payable'));
$name_flag = 0;
$pay_flag = 0;
echo "<table border='1'>";
for($i=0;$i<count($name_arr);$i++)
{
for($j=0;$j<count($payable_arr);$j++)
{
foreach($result as $list)
{
if($list['Name'] == $name_arr[$i] && $list['Payable'] == $payable_arr[$j])
{
if($name_flag==0 && $pay_flag==0)
{
echo "<tr>";
echo "<td>".$name_arr[$i]."</td>";
echo "<td>".$payable_arr[$j]."</td>";
echo "<td>".$list['Product']."</td>";
echo "<td>".$list['Quantity']."</td>";
echo "</tr>";
}
else
{
echo "<tr>";
echo "<td> </td>";
echo "<td> </td>";
echo "<td>".$list['Product']."</td>";
echo "<td>".$list['Quantity']."</td>";
echo "<tr>";
}
$name_flag++;
$pay_flag++;
}
}
}
$name_flag=0;
$pay_flag=0;
}
echo "</table>";
?>

Find prev/next id without knowing current position (PHP & MySQL)

This is my first time posting here so please bear with me.
I'm creating an image gallery using HTML & CSS, where I show one image on the screen and it has a prev/next button to toggle through the images (at no point does this take you to a new webpage). I'm using PHP & MySQL to populate the images.
So, I have a table like this:
| ID | Name | Genre |
--------------------------------
| 1 | Apple | Fruit |
--------------------------------
| 2 | Cabbage | Veg |
--------------------------------
| 3 | Lettuce | Veg |
--------------------------------
| 4 | Pear | Fruit |
--------------------------------
| 5 | Banana | Fruit |
--------------------------------
| 6 | Leek | Veg |
--------------------------------
| 7 | Kiwi | Fruit |
I want to only images where genre=fruit, so now my table is like the following:
| ID | Name | Genre |
--------------------------------
| 1 | Apple | Fruit |
--------------------------------
| 4 | Pear | Fruit |
--------------------------------
| 5 | Banana | Fruit |
--------------------------------
| 7 | Kiwi | Fruit |
Since the IDs are no longer incremental, I can no longer simply use $id-1 or $id+1 to get the prev/next photos.
This is what my PHP code looks like (simplified for this post):
<?php
$sql = "SELECT * FROM photo WHERE genre LIKE '%fruit%' ORDER BY id DESC";
$result = mysql_query($sql, $conn) or trigger_error("SQL", E_USER_ERROR);
while ($rows = mysql_fetch_assoc($result)) {
$id=$rows['id'];
$name=$rows['name'];
$genre=$rows['genre'];
echo "<div id=\"img$id\">".
"<".
">".
"<img src=\"img/full/$name.jpg\">".
"</div>";
} // end while
?>
Since I'm loading all of the fruit photos, I don't know what is the current ID and I won't know how many rows there will be displayed in total. I'd like to find the ID of the row item that is before and after the current row/photo the user sees.
I've tried using current(), next(), and prev() but they all seem to select the first 3 rows only. Any help would be so greatly appreciated! Been researching this all day and haven't been able to solve this :( Thanks so much in advance.
Here's a sample code with comments:
$images = [];
while ($rows = mysql_fetch_assoc($result)) {
// first we store images in an array
$images[] = [
'id' => $rows['id'],
'name' => $rows['name'],
'genre' => $rows['genre'],
];
}
// next we iterate over this array
foreach ($images as $index => $image) {
echo '<div id="img' . $image['id'] . '">';
// as array is numerically indexed
// we can get previous item's index as `$index - 1`
// and check if it is set
if (isset($images[$index - 1])) {
// if it is set - we output it
echo '<';
}
// as array is numerically indexed
// we can get next item's index as `$index + 1`
// and check if it is set
if (isset($images[$index + 1])) {
// if it is set - we output it
echo '>';
}
echo '<img src="img/full/' . $image['name'] . '.jpg">';
echo '</div>';
}

mySQL query to dynamically convert column data to column name

I am trying to create a 'run sheet' of doughnut orders from a ZenCart database. I read a dozen posted questions to get to [Jeff Lee's response to question]: SQL query to rebuild a table using its dynamic row data for column names. Since I am using MySQL, I think I need to generate a dynamic query because my 'ProductName' data changes.
I have written the following code which generates an HTML table similar in structure to the example database table but I do not know how to incorporate his solution into my code as I am not starting with a database table but rather a query result-set.
I am going to try creating a database table from my existing query in order to use Jeff's solution but I think the preferred method would be to incorporate his code into my query, I just don't know how.
I am using PHP/5.6.11 and MySQL/5.6.25
<?php
echo 'Attempt connection to the [donutsdb] database';
print '<br />';
require("includes/connect2donutsdb.php");
?>
<?php
//this script will query the 'orders' and 'orders_products' tables
//and combine the information based on the 'orders_id' field
//I added aliases to improve the query readability
try {
echo '[donutsdb]';
print '<br />';
$query = "
SELECT
o.orders_id AS 'O_OID', o.customers_name AS 'O_CName',
p.products_name AS 'P_PName', p.products_quantity AS 'P_PQuant'
FROM
orders AS o
INNER JOIN orders_products AS p
ON o.orders_id=p.orders_id
";
//first pass just gets the column names
print "<table> \n";
$result = $dbh->query($query);
//return only the first row (we only need field names)
$row = $result->fetch(PDO::FETCH_ASSOC);
print " <tr> \n";
foreach ($row as $field => $value){
print " <th>$field</th> \n";
} // end foreach
print " </tr> \n";
//second query gets the data
$data = $dbh->query($query);
$data->setFetchMode(PDO::FETCH_ASSOC);
foreach($data as $row){
print " <tr> \n";
foreach ($row as $name=>$value){
print " <td>$value</td> \n";
} // end field loop
print " </tr> \n";
} // end record loop
print "</table> \n";
print '<br />';
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
} // end try
?>
My code generates an HTML table with the following structure:
O_OID | O_CName | P_PName | P_PQuant
1 | mark | Glazed | 12
2 | John | Glazed | 8
2 | John | Bavarian Cream | 4
3 | mark | Chocolate Dipped | 12
4 | Kevin | Donut Holes | 10
5 | Kevin | Peanut Butter | 1
5 | Kevin | Blueberry | 2
What I am trying to achieve is:
O_OID | O_CName | Glazed | Bavarian Cream | Chocolate Dipped | Donut Holes | Peanut Butter | Blueberry
1 | mark | 12 | 0 | 0 | 0 | 0 | 0
2 | John | 8 | 4 | 0 | 0 | 0 | 0
3 | mark | 0 | 0 | 12 | 0 | 0 | 0
4 | Kevin | 0 | 0 | 0 | 10 | 1 | 2

Parsing table and removing excess data

Im using the simpel dom parser to retrieve som data. But when i changed the table layout the parser stopped working. Im getting error PHP Fatal error: Call to a member function find() on null.
require('simple_html_dom.php');
$html = file_get_html($url);
$table = $html->find('table');
$rowData = array();
foreach($table->find('tr') as $row) {
// initialize array to store the cell data from each row
$stocks = array();
foreach($row->find('td') as $cell) {
// push the cell's text to the array
$stocks[] = $cell->plaintext;
}
$rowData[] = $stocks;
}
echo '<table>';
foreach ($rowData as $row => $tr) {
echo '<tr>';
foreach ($tr as $td)
echo '<td>' . $td .'</td>';
echo '</tr>';
}
echo '</table>';
Have a look at this pastebin (sorry for big table layout). It is from this table i want to extract the following th
+--------+--------+------+----+------+-------+--------+--------+---------+
| Aktie | Senast | +/- | % | Köp | Sälj | Högst | Lägst | Omsatt |
+--------+--------+------+----+------+-------+--------+--------+---------+
This snipp works, but it doesn't arrange the data in a table:
require('simple_html_dom.php');
$html = file_get_html($url);
// remove all image
foreach($html->find('img') as $e)
$e->outertext = '';
// Remove a attribute, set it's value as null!
foreach($html->find('a') as $e)
$e->href = null;
// Find all <td> in <table> which class=hello
foreach($html->find('table tr') as $es)
echo $es->innertext . '<br>';
My question:
How can i fetch the above mentioned th? and insert the corresponding data from td column?
Expected result is:
+-------------+--------+-------+-------+-------+-------+--------+--------+---------+
| Aktie | Senast | +/- | % | Köp | Sälj | Högst | Lägst | Omsatt |
+-------------+--------+-------+-------+-------+-------+--------+--------+---------+
| AAK AB | 549,90 | ..etc | ..etc | ..etc | ..etc | ..etc | ..etc | ..etc |
| ABB LTD | 149.80 | ..etc | ..etc | ..etc | ..etc | ..etc | ..etc | ..etc |
| and so on.. | | | | | | | | |
+-------------+--------+-------+-------+-------+-------+--------+--------+---------+
Do you have more than one table? If so, explicitly identify the table id
Get header: $e = $table->find('thead'); and do something to it get the table data, as you already did, and I would imagine that the indexes could implicitly create the relation between header and data.

PHP display images from column value

Table
+-----+--------+---------+
| ID | Name | Images |
+-----+--------+---------+
| 001 | John | 5 |
| 002 | Mark | 3 |
+-----+--------+---------+
i would like to display like this
Jon, 001-1.jpg | 001-2.jpg | 001-2.jpg | 001-3.jpg | 001-4.jpg | 001-5.jpg |
Mark, 002-1.jpg | 002-2.jpg | 002-2.jpg | 002-3.jpg |
the images value on database table will be the number of images return to create images link
You can use this though. Didn't know why you found it difficult.
$c = 0
while (false !== ($data = fetch_array_as_row_function()))
{
echo "<tr>";
echo "<td>", $data["name"], "</td>";
for ($i = 0; $i < $data["images"]; $i++)
echo "<td>00", $c,"-", $i, "</td>";
echo "</tr>";
}
Here, the function fetch_array_as_row_function() is something equivalent to what mysql_fetch_array() does.

Categories