mysql query to html table - php

I want to show the query results of mysql query in a table,
There are two tables, and some information has to be retrieved from the second table
I want to retrieve title, borrower name and borrower surname from other tables,
I tried to retrieve title, but I was unsuccessful,
Then I want to retrieve the borrower name and borrower surname from the users table
You may also offer a new way to put the results into a table
Here is the code
for($i=0;$i<999999999;$i++){
$sql="SELECT * FROM products WHERE product_id='$i' LIMIT 1";
//echo $sql;
$moviename="SELECT dbid FROM products WHERE product_id='$i'";
$dbid=mysql_query($moviename);
$movname="SELECT title FROM titles WHERE dbid='$dbid' ";
$name=mysql_query($movname);
$title=mysql_fetch_array($name);
print "<table border=1>
<tr><th>Product_ID</th>
<th>dbid</th>
<th>Title</th>
<th>Status</th>
<th>Date</th>
<th>Borrowe_id</th>
<th>Borrower Name</th>
<th>Borrower Surname</th></tr>";
$result=mysql_query($sql);
if($result==NULL){
continue ;
}
while ($row = mysql_fetch_array($result))
{
print "<tr><td>{$row[1]}</td>
<td>{$row[2]}</td>
<td>{$title[0]}</td>
<td>{$row[12]}</td>
<td>{$row[13]}</td>
<td>{$row[14]}</td>
<td>{$borrowername[0]}</td>
<td>{$borrowesurname[0]}</td></tr>";
}
print "</table>";
}
?>

There are a few things going on here which you should definitely not be doing.
Super insane loop with a query inside
for($i=0;$i<999999999;$i++){
// SELECT STATEMENT HERE!
}
Why are you looping potentially 999,999,999 times? And if you do you are going to hit your database 999,999,999 times? That is going to kill your database and it can be done much more efficiently.
Use joins over individual selects
$sql="SELECT * FROM products WHERE product_id='$i' LIMIT 1";
$moviename="SELECT dbid FROM products WHERE product_id='$i'";
$movname="SELECT title FROM titles WHERE dbid='$dbid' ";
Note:
product_id='$i' LIMIT 1
Usually you want your ids to be unique. Why do you need to LIMIT your query?
The query can be simplified to:
select
*
from
products p
left outer join titles t
on p.dbid = t.dbid
Note: SELECTING * IS BAD PRACTICE, BUT I DON'T KNOW WHAT YOUR STRUCT IS
Illogical logic
if($result==NULL){
continue ;
}
while ($row = mysql_fetch_array($result)) {...}
$result is null at this point, so your while loop will never happen.
So after killing that loop, simplifying the query, and revising logic... we can do:
$result_resource = mysql_query($sql);
echo"
<table border=1>
<tr>
<th>Product_ID</th>
<th>dbid</th>
<th> Title</th>
<th>Status</th>
<th>Date</th>
<th>Borrowe_id</th>
<th>Borrower Name</th>
<th>Borrower Surname</th>
</tr>";
while ($row = mysql_fetch_array($result_resource))
{
echo "
<tr>
<td>{$row['ProductID']}</td>
<td>{$row['dbid']}</td>
<td>{$row['Title']}</td>
<td>{$row['Status']}</td>
<td>{$row['Date']}</td>
<td>{$row['Borrowe_id']}</td>
<td>{$borrowername[0]}</td>
<td>{$borrowesurname[0]}</td>
</tr>";
}
echo "</table>";
Looking at $borrower.... I have a feeling you can also join your borrow table to the query to bring that in too.
I would also look into templating. It would definitely separate your data from your display and make your code a lot easier to read.

First,you should debug your code
one thing that pops up is the following error:
you should change the following from:
print "<tr><td>{$row[1]}</td>
<td>{$row[2]}</td> ..."
to:
print "<tr><td>{" . $row[1] . "}</td>
<td>{" . $row[2] . "}</td> ..."
Second, when you say " I was unsuccessful" - please add details, did you get an error ? what was the output ?

(Maybe your question is "too localize")
First I don't recommend this :
for($i=0;$i<999999999;$i++)
because it will take long for the server to compute, and generate a lot of mysql query.
Second, most (all?) of your mysql queries could be merge in only one query.
You can about query on more then one table here (dev.mysql.com) There's several way to join multiples tables, you could read about it
Third, in your code the table header will be repeated each time, because it's in your For loop.
here my suggest to improve your code :
//Print the header
print "<table border=1>
<tr><th>Product_ID</th>
<th>dbid</th>
<th>Title</th>
<th>Status</th>
<th>Date</th>
<th>Borrowe_id</th>
<th>Borrower Name</th>
<th>Borrower Surname</th></tr>";
//adapt the following sql with your tables name / fields
$sql="SELECT products.product_id, products.dbid, title.tiles, product.status, product.date, borrow.id , borrow.name, borrow.surname FROM products,titles,borrow WHERE product.dbid = titles.dbid && borrow.id = product.prodict_id LIMIT 1";
$result=mysql_query($sql);
while ($row = mysql_fetch_array($result))
{
print "<tr><td>{$row[1]}</td>
<td>{$row[2]}</td>
<td>{$row[3]}</td>
<td>{$row[4]}</td>
<td>{$row[5]}</td>
<td>{$row[6]}</td>
<td>{$row[7]}</td>
<td>{$row[8]}</td></tr>";
}
print "</table>";
?>
I know that the sql query isn't the best one, but I think those suggestions could help you.

Here is a function for you to convert any MySQL select statement to a HTML table with table headings.
function createTable_from_sql_select_query($query) {
$sql_link = Connect_MySQLi_DB(); // Your Database Connection
$sql_link->set_charset("utf8");
$result = $sql_link->query($query);
// Adding Missing Array Column Function for Old PHP Versions (<5.5)
if (!function_exists('array_column')) {
function array_column($array, $column) {
$ret = array();
foreach ($array as $row)
$ret[] = $row[$column];
return $ret;
}
}
$headings = json_decode(json_encode($result->fetch_fields()), true);
$headings = array_column($headings, 'name');
$return = '<table>';
$return .= '<thead><tr>';
for ($x = 0; $x <= (count($headings) - 1); $x++) {
$return .= '<th>' . ucwords(str_replace('_', ' ', (strtolower($headings[$x])))) . '</th>';
}
$return .= '</tr></thead><tbody>';
while ($row = $result->fetch_object()) {
$return .= '<tr>';
for ($x = 0; $x <= (count($headings) - 1); $x++) {
$return .= '<td>' . $row->$headings[$x] . '</td>';
}
$return .= '</tr>';
}
$return .= '</tbody></table>';
return $return;
}

Related

PHP display data in table using foreach loop

I have the 2020 hurricane name and all the states. I want to loop through my database and see if the options are picked. If they are, populate the spot with the name. If not, add"--". It will look almost like a spreadsheet of data.
When I submit data, it doesn't populate in the right spot and add a bunch of empty cells.
This is my queries:
// DB Connection
$db_connection = mysqli_connect('localhost','root','','hurricane_bowl');
$i = "SELECT * FROM users RIGHT JOIN states USING (state_id) GROUP BY (state_name) ORDER BY state_name ASC";
$state = mysqli_query($db_connection, $i);
$g = "SELECT * FROM users RIGHT JOIN hurricanes USING (hurricane_id) GROUP BY (hurricane_name) ORDER BY hurricane_name ASC";
$hurricane = mysqli_query($db_connection, $g);
This is my loops:
<table class="table table-striped table-bordered">
<thead>
<tr>
<th scope="col">Hurricane Name</th>
<?php
foreach($state as $stval) {
echo '<th scope="col">' . $stval['state_name'] . '</th>';
}
?>
</tr>
</thead>
<tbody>
<?php
foreach($hurricane as $h) {
echo '<tr>';
echo '<th scope="row">' . $h['hurricane_name'] . '</th>';
foreach($state as $st) {
if($st['state_id'] != NULL && $h['hurricane_id'] != NULL) {
echo '<td>' . $st['username'] . '</td>';
} else {
echo '<td>--</td>';
}
}
echo '</tr>';
}
?>
</tbody>
</table>
The first change needs to be to the queries: if you want to display three separate query results, you need three separate tables, otherwise it makes not sense because there is no connection between the three datasets you are retrieving. Alternatively, you need just one dataset. Use JOIN in a query to link multiple table results, assuming there is a link between the tables.
W3Schools on this topic: https://www.w3schools.com/sql/sql_join.asp
Secondly, when loops are nested, each layer is its own dimension. In your case, you are trying to create a sort of 3-dimensional table, which can't work. Typically for a query result you only need one foreach loop, but if you don't have any information on the table fields, you can have two, not more.

Trying to get MySQL results to display horizontally

I'm creating a webpage that lists ten characters in a game based on their experience levels and displays them with a picture associated each character. My code works, but the output is in a column when I'd like it to be in a row. I did see where something very similar had been asked here: MySQL data from database align horizontally and I tried to follow that example but either ended up with errors or the faces didn't appear. I'm a hobbyist, I'm just doing this for friends, so my knowledge is pretty basic.
Relevant code:
<table border="3" width="90%">
<tr>
<th width="25%">XP</th>
<td>
<?php
$resultgood = mysqli_query($con,"SELECT * FROM Life WHERE goodxp > 0 ORDER BY goodxp DESC LIMIT 10");
while($row = mysqli_fetch_array($resultgood))
{
$face = mysqli_query($con,"SELECT face FROM Description WHERE charname='$row[charname]'");
$row = mysqli_fetch_row($face);
$face = $row[0];
$name = mysqli_query($con,"SELECT charname FROM Life WHERE charname='$row[charname]'");
$row = mysqli_fetch_row($name);
$name = $row[0];
echo "<left>";
echo "<table border='1'>";
echo "<tr><td>";
echo "<img src='pictures/$face' alt='$name' border='2'>";
echo "</td></tr>";
echo "</table>";
echo "<br>";
}
?>
</td>
</tr>
</table>
Anyone got any suggestions? Thanks!
So after following Bombelman's suggestion below, I got it to work. In case anyone else runs into this problem, here is the working code:
<tr>
<th width="25%">Goody Two Shoes</th>
<td><?php
echo "<table border='1'><tr>";
echo "<left>";
$resultgood = mysqli_query($con,"SELECT * FROM Life WHERE goodxp > 0 ORDER BY goodxp DESC LIMIT 10");
while($row = mysqli_fetch_array($resultgood))
{
$face = mysqli_query($con,"SELECT face FROM Description WHERE charname='$row[charname]'");
$row = mysqli_fetch_row($face);
$face = $row[0];
$name = mysqli_query($con,"SELECT charname FROM Life WHERE charname='$row[charname]'");
$row = mysqli_fetch_row($name);
$name = $row[0];
echo "<td>";
echo "<img src='pictures/$face' alt='$name' border='2'>";
echo "</td>";
}
echo "</tr>";
echo "</table>";
?></td>
</tr>
place the "table" and "row" tag out of the loop, and have the results in between the "td" tags looped only.
Looking at your script, you have several tables.
Make sure only the < td > and < /td > tags are within the while-loop.
The output should be similar to my example.
Hope it helps !
<table style="width:100%">
<tr>
<td>Character 1</td>
<td>Character 2</td>
<td>Character 3</td>
<td>Character 4</td>
<td>Character 5</td>
</tr>
</table>
Looking at the sql queries makes me think you ought to be able to do a basic join upon the two tables rather than having nested queries within a loop. The generation of the html table should be fairly straightforward - iterate through the recordset results for rows in the table and iterate through the fields returned by the query for individual cells within the table row.
$sql='select l.*, d.face from `life` l
join `description` d on d.`charname`=l.`charname`
where l.`goodxp` > 0
order by l.`goodxp` desc
limit 10';
$res=$con->query( $sql );
/* fetch the column names into an array */
$fields=array();
array_walk( $res->fetch_fields(),function( $item, $key, $fields ){
$fields[]=$item->name;
},&$fields );
$html=array();
$html[]='<table>';
/* add field names as column headers */
$html[]='<tr>';
foreach( $fields as $field )$html[]='<th>'.$field.'</th>';
$html[]='</tr>';
/*
iterate through recordset,
add new row for every record
but table cell for every
field in record
*/
while( $rs=$res->fetch_object() ){
$html[]='<tr>';
foreach( $fields as $field ){/* show image or text */
$data = $field=='face' ? "<img src='pictures/{$rs->$field}' />" : $rs->$field;
$html[]='<td>'.$data.'</td>';
}
$html[]='</tr>';
}
$html[]='</table>';
/* render table */
echo implode( PHP_EOL, $html );
Depending upon the version of PHP you may get nagged at when using the array_walk function and passing the third argument by reference. If that is the case then change
$fields=array();
array_walk( $res->fetch_fields(),function( $item, $key, $fields ){
$fields[]=$item->name;
},&$fields );
for
$fields=array();
array_walk( $res->fetch_fields(),function( $item, $key ){
global $fields;
$fields[]=$item->name;
} );

Search the results from a query

I have a site where members can mark other members as 'a favourite'. User are able to search the members table in various ways and I want to show from any of the results that are returned whether or not the users returned are favourites of the current user.
This is some very simplified code I have been using to try and get this query to work but I just can't figure it out. Whenever I add 'GROUP BY' to avoid duplicate results from my LEFT JOIN the 'if' statement does not work. The 'if' statment does work however, if I omit the 'GROUP BY' but I get all rows from members table and the favourites table. Thanks.
$result = mysqli_query($db_conx, "SELECT members.*, user_favourites.* FROM members LEFT JOIN user_favourites ON members.id = user_favourites.fav_id GROUP BY members.id");
echo "<table border=''>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>A favourite of User</th>
</tr>";
while($row = mysqli_fetch_array($result)) {
echo "<tr>";
echo "<td>" . $row['firstname'] . "</td>";
echo "<td>" . $row['lname'] . "</td>";
echo "<td>" . $row['email'] . "</td>";
if ($visitor == $userid ){
$msgs = "x";
}
else { $msgs = "0";
}
echo "<td>". $msgs. "</td>";
echo "</tr>";
}
echo "</table>";
mysqli_close($con);
?>
I suggest to you, tu use 2 query's insted one. Simple query is a fast querys. If your site scale up, your query will be slow query and it cause performance problems.
Idea:
For one hand: SELECT FROM members, get all and put it inside array, key=member.id
$members[$row['member_id']]=$row;
On the other hand: SELECT * FROM user_favourites, and put it inside the previous array, refereced by the key fav_id use distinc if you have duplicates.
$members[$row['fav_id']]['favourites']=$row;
Perfect now you have all you need, an array with all information, iterate it.
JilianJ something like this:
<?
//Prepare
$all_users=array()
$query_users='SELECT * from user';
$query_favourites='SELECT * FROM user_favourites';
//Now I find all members information
$users=mysqli_query($db_conx,$query_users);
while($user = mysqli_fetch_array($users)) {
$all_users[$user['id']]=$user;
}
//Now I add favourite information to the users information
$favourites=mysqli_query($db_conx,$query_favourites);
while($favourite = mysqli_fetch_array($favourites)) {
$all_users[$favourite['fav_id']]['fovourite'][]=$favourite['fav_id'];
}
?>
<table>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>A favourite of User</th>
</tr>
<? foreach ($information as $key=>$item) {?>
<tr>
<td><?=$item['firstname'];?></td>
<td><?=$row['lname'];?></td>
<td><?=$row['email'];?></td>
<td>
<? foreach($item['favourites'] as $key2=>$item2) { ?>
<p><?=$all_members[$item2]['name];?></p>
<? } ?>
</td>
</tr>
<? } ?>
</table>
Good luck

How to sort data tables using the header row by alphabetical order

Im doing a sch project and I need help in sorting my data table in alphabetical order by clicking the header row. Im using MySQL and I intend to use a php to implement it. Can anyone help me? Thanks.
This is my code:
This is a php file.
<?php
# $db = new mysqli('localhost', 'f33s01', 'f33s01', 'f33s01');
if (mysqli_connect_errno()) {
echo 'Error: Could not connect to database. Please try again later.';
exit;
}
$query = "select * from gyms";
$result = $db->query($query);
$num_results = $result->num_rows;
echo "<table border=\"3\" cellpadding=\"5\" class=\"dirtable\" style=\"margin-bottom:15px\">
<tr align=\"center\" class=\"gold\">
<th>Number</th>
<th>Gym Name</th>
<th>Address</th>
<th>Location</th>
<th width=\"18%\">Operating Hours</th>
<th>Reservation</th>
</tr>";
for ($i=0; $i <$num_results; $i++) {
$row = $result->fetch_assoc();
echo "<tr>";
echo "<td align=\"center\">".($i+1)."</td>";
echo "<td align=\"center\">".stripslashes($row['gymname'])."</td>";
echo "<td>".stripslashes($row['address'])."</td>";
echo "<td>".stripslashes($row['location'])."</td>";
echo "<td align=\"center\">".stripslashes($row['operatinghours'])."</td>";
echo "<td align=\"center\"><input type= \"submit\" value=\"BOOK NOW\" class=\"bookbutton\"></td>";
echo "</td>";
echo "</tr>";
}
echo "</table>";
echo "</form>";
$result->free();
$db->close();
?>
To strictly answer your question, you can use links in the column headings to pass $_GET variables to your page, and customize your mysql queries with SORT BY in order to render the data. I'll give a rough outline, this should get you pointed in the right direction. You will need to add in more logic on the heading urls to enable sorting in multiple directions.
For the heading:
echo "<th><a href='".$_SERVER[REQUEST_URI]."?orderby=gymname&order=desc'>Gym Name</a>";
And then before your mysql code, have a switch statement
switch($_GET[orderby]) {
case "gymname":
$filter_orderby = "gymname";
break;
case "address":
$filter_orderby = "address";
break;
//...other cases...
}
switch($_GET[order]) {
case "desc":
$filter_order = "DESC";
break;
case "asc":
$filter_order = "ASC";
break;
}
Now, you can append those to your query:
$myquery = "SELECT * FROM gyms WHERE 1 = 1";
if(isset($filter_orderby) {
$myquery .= " ORDER BY ".$filter_orderby." ".$filter_order;
}
//Result: SELECT * FROM gyms WHERE 1 = 1 ORDER BY gymname DESC
If this data is not paginated or otherwise in a non-flat presentation then I would agree with Nikita Singh's suggestion of using a jQuery plugin - another is http://tablesorter.com/

mysql query giving incorrect result in for loop

The code belows gives me only 18 records
<?php
$result4 = mysql_query("select Distinct Country from trendsmtable where WHORegionAC='Europe - all countries' GROUP BY Country ");
echo "<table width=880 align=center>";
echo "<tr><td colspan=4 style='font-family:Arial;'><b>European Region</b></td></tr>";
$num_columns4 = 4;
$num_rows4 = mysql_num_rows($result4);
$i=0;
while($row4 = mysql_fetch_assoc($result4)){
$results[$i] = $row4['Country'];
$i++;
}
unset($i);
$k=0;
for ($i=0;$i<=($num_rows4/($num_columns4+1));$i++){
echo '<tr>';
for($j=1;$j<=$num_columns4;$j++){
echo "<td width=220 style='font-family:Arial; font-size:12px'>".$results[$k].'</td>';
$k++;
}
echo '</tr>';
$k++;
}
echo "</table>";
?>
while the select statement
select Distinct Country from trendsmtable where WHORegionAC='Europe -
all countries'
returns 22 rows while I execute it in mysql which is correct!
Please help me to found the error.
Well, you have an extra $k++ in there that you don't need:
$k++; // keep this one
}
echo '</tr>';
$k++; // remove this one
}
Edit
I've gone through your code and I've made some edits. Hopefully they'll clean your issue along the way:
// got rid of group by. With a select distinct, it isn't necessary
$result4 = mysql_query("select Distinct Country from trendsmtable where ".
"WHORegionAC='Europe - all countries'");
// a good practice is to always double-quote your HTML attributes.
echo "<table width=\"880\" align=\"center\">";
echo "<tr><td colspan=4 style=\"font-family:Arial;\">".
"<b>European Region</b></td></tr>";
$num_columns4 = 4; // where does 4 come from.
// $results was never initialized before.
$results = array();
while($row4 = mysql_fetch_assoc($result4)){
// This is generally thought of as "cleaner" than using an index.
// And since there cannot be more than, say, 220 rows, cleanliness
// should be a high-priority standard.
$results[] = $row4['Country'];
}
// mysql_num_rows rarely provides any major benefit at all.
$num_rows4 = count($results);
foreach( $results as $key => $val )
{
// This happens every time we fill all columns and need a new row.
if( !( $key % $num_columns4 ) )
{
// makes it so that after the first time this closes the prev
// row before starting a new one.
if( $key ) echo '</tr>';
echo '<tr>';
}
// insert nag about CSS
echo '<td width="220" style="font-family:Arial; font-size:12px">'.
$val.
'</td>';
}
echo '</tr></table>';
I think the PHP looks a little odd, it looks like you are looping from 0 to (22 / 5)
then in the inner loop 4 times.
The group by should not make any difference as you are doing a select distinct
Your SQL code in the PHP file contains a GROUP BY clause, which can reduce the number of rows returned, if you have a country more than once in the db.

Categories