Print calculated Value of variable before its been calculated - php

This is a tricky question to search, hence my post here. I have a a header that displays the sum of all the values in a column of a table that is printed below it. However the table is generated from a MYSQL table and the sum of the column values is calculated as it is generated. So somehow I have to have a variable printed but only after the table is generated and I am not sure how to pass the variables back up to the print statement so it doesn't always print out a 0
I feel like the solution is that the sum should call a script (Javascipt) that generates and prints the table returning the sum of columns to then be printed. But I am not sure how I would do this
echo "
<h3>EPL</h3>
<h5>Total Score: $total</h5>
<table class='table table-bordered'>
<tr>
<th>#</th>
<th>Name</th>
<th>Score</th>
</tr>
<tbody class='row_position'>"?>
<?php
require('db_config.php');
$tablename = $_SESSION['username'] . "_epl";
$_SESSION['tablename'] = $tablename;
$sql = "SELECT * FROM $tablename ORDER BY position_order";
$users = $mysqli->query($sql);
while($user = $users->fetch_assoc()){
$con = mysqli_connect('localhost', 'root', 'root', 'predictions');
$sql1 = "SELECT * FROM `predictions`.`".$tablename."` WHERE (CONVERT(`title` USING utf8) LIKE '%".$user['title']."%')";
$sql2 = "SELECT * FROM `predictions`.`epl` WHERE (CONVERT(`title` USING utf8) LIKE '%".$user['title']."%')";
$result = mysqli_query($con, $sql1);
$row = $result->fetch_assoc();
$position1 = $row['position_order'];
$result->close();
$result = mysqli_query($con, $sql2);
$row = $result->fetch_assoc();
$position2 = $row['position_order'];
$total += abs($position1-$position2);
?>
<tr id="<?php echo $user['id'] ?>">
<td><?php echo $user['position_order'] ?></td>
<td><?php echo $user['title'] ?></td>
<td><?php echo abs($position1-$position2); ?></td>
</tr>
<?php } ?>
</tbody>
</table>
To explain the table further, each user has their own table with the same format username_league, so I use some php code to grab the table. Additionally I have a base case table in this case 'epl' in which I compare the tables and calculate the scores based on the absolute difference in the column 'position_order'.

You should always aim for separation of your code and presentation. And beyond that, your database code is extremely inefficient. You're re-creating an entire database object for every instance of your original query.
Just put your PHP code before the HTML, or better yet in a separate file.
<?php
$total = 0;
require('db_config.php');
$tablename = $_SESSION['username'] . "_epl";
$_SESSION['tablename'] = $tablename;
$sql = "SELECT id, position_order, title FROM `$tablename` ORDER BY position_order";
$users_result = $mysqli->query($sql);
while($user = $users_result->fetch_assoc()) {
$users[] = $user;
}
foreach ($users as $user) {
$sql1 = "
SELECT position_order FROM `$tablename` WHERE CONVERT(`title` USING utf8) LIKE '%$user[title]%' LIMIT 1
UNION
SELECT position_order FROM `epl` WHERE CONVERT(`title` USING utf8) LIKE '%$user[title]%' LIMIT 1
";
$result = $mysqli->query($sql1);
$row = $result->fetch_assoc();
$position1 = $row['position_order'];
$user["position1"] = $position1;
$row = $result->fetch_assoc();
$position2 = $row['position_order'];
$user["position2"] = $position2;
$total += abs($position1 - $position2);
}
?>
There you are; using a single database object, one third fewer queries, all your values in an array. They're ready to use later in the file, or in your separate HTML view:
<h3>EPL</h3>
<h5>Total Score: <?=$total?></h5>
<table class='table table-bordered'>
<tr>
<th>#</th>
<th>Name</th>
<th>Score</th>
</tr>
<tbody class='row_position'>
<?php foreach($users as $user):?>
<tr id="<?=$user['id'] ?>">
<td><?=$user['position_order'] ?></td>
<td><?=$user['title'] ?></td>
<td><?=abs($user["position1"]-$user["position2"]); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
I don't know enough about the structure here, but I'd be very surprised if you couldn't make this a single database query.

Output buffering is your friend! Simply call ob_start before outputting the table i.e.
ob_start();
echo "
<table class='table table-bordered'>
<tr>
<th>#</th>
<th>Name</th>
<th>Score</th>
</tr>
<tbody class='row_position'>"?>
...
then once you have done generating the table, you can collect the output of the table's content using ob_get_clean, output the header and then the table content:
...
$table = ob_get_clean();
echo "<h3>EPL</h3>
<h5>Total Score: $total</h5>";
echo $table;

Related

Displaying SQL Query in HTML table (php)

Trying to get counts from 2 different tables into a simple HTML table.
This is my code:
$sql = "SELECT COUNT(*) FROM tasks";
$result = $conn->query($sql);
$rowcount=mysqli_num_rows($result);
if ($result->num_rows > 0) { ?>
<table style="width:100%">
<tr>
<th>Total</th>
</tr>
<?php while($row = $result->fetch_assoc()) { ?>
<tr>
<td><?=$rowcount;?></td>
</tr>
<?php } ?>
</table>
<?php } else { echo "0 results"; } ?>
When I run the code, it shows the amount of rows in the table, but it also creates the amount of rows with the number in it (i.e. 281 rows).
Table
281
281
281
281 etc.
My idea was to copy and paste the above to show a second table set of results (if it was correct), but is there a better way of doing this? I've been looking at how I would display SELECT (select COUNT(*) from tasks) , (select count(*) from quotes) into the following format (HTML):
Table
Count
Tasks
281
Quotes
42000
First of all your query does produces only one row for a table, not 281.
The second - I omit usage of prepared SQL statements with placeholders, which should always be used in a real project whenever applyable.
$rows = [];
foreach(['Tasks', 'Quotes'] as $table ){
$result = $conn->query("SELECT '$table' as 'table', count(*) as 'count' FROM $table");
if( $result )
$rows[] = $result->fetch_assoc();
}
if( empty( $rows ) )
print "0 results";
else {?>
<table style="width:100%">
<tr><th>Table</th><th>Count</th></tr>
<?=implode(
"\n",
array_map(function($row){
return "<tr><td>${row['table']}</td><td>${row['count']}</td></tr>";
}, $rows)
)?>
</table>
<?php }
I've been looking at how I would display SELECT (select COUNT() from
tasks) , (select count() from quotes) into the following format
(HTML)
You can just run the queries query, and use the result of the first to create the first row of the table, then the result of the second to create the second row. Since COUNT queries always return exactly 1 row when there's no GROUP BY, it's quite simple to do really:
$sql1 = "SELECT COUNT(*) FROM tasks";
$result1 = $conn->query($sql1);
if ($row = $result1->fetch_array()) $taskCount = $row[0];
else $taskCount = "error";
$sql2 = "SELECT COUNT(*) FROM quotes";
$result2 = $conn->query($sql2);
if ($row = $result2->fetch_array()) $quoteCount = $row[0];
else $quoteCount = "error";
?>
<table style="width:100%">
<tr>
<th>Table</th>
<th>Count</th>
</tr>
<tr>
<td>Tasks</td>
<td><?php echo $taskCount; ?></td>
</tr>
<tr>
<td>Quotes</td>
<td><?php echo $quoteCount; ?></td>
</tr>
</table>
Another way, if you want the HTML structure to be less repetitive / dependent on the tables queries, is to UNION the SELECTs into a single query:
$sql = "SELECT 'Tasks' AS 'table', COUNT(*) as 'count' FROM tasks";
$sql .= " UNION ";
$sql .= "SELECT 'Quotes' AS 'table', COUNT(*) as 'count' FROM quotes";
$result = $conn->query($sql);
?>
<table style="width:100%">
<tr>
<th>Table</th>
<th>Count</th>
</tr>
<?php
while ($row = $result->fetch_assoc()) { ?>
<tr>
<td><?php echo $row["table"]; ?></td>
<td><?php echo $row["count"]; ?></td>
</tr>
<?php
}
?>
</table>

Mysql Php Pagination for varios table

I have this pagination script
1 Show-page
$result_p = mysqli_query($conexao, "select count(*) as count FROM `banner-destaque`");
$row_p = mysqli_fetch_array($result_p);
$quant_resul = 10;
$pagina = 1;
$paginas = ceil($row_p['count'] / $quant_resul);
$result = mysqli_query($conexao, "select * FROM `banner-destaque` limit 0 , " . $quant_resul);
The script works fine to one mysql table, but I need to reuse the same pagination script for other mysql tables with diferent sizes.
This is the table that show te results
<table class="flat-table flat-table-1">
<thead>
<th>Id</th> **//Here i need get tables columns name to make it dinamically for reuse in other tables**
<th>Photo</th>
<th>Title</th>
<th>Description</th>
</thead>
<tbody>
<tr>
<?php
while ($row = mysqli_fetch_object($result)) {
echo
'
//and here i need get all columns values to populate the above column.
<td>'.$row->id.'</td>
<td>'.$row->foto.'</td>
<td>'.$row->titulo.'</td>
<td>'.$row->descricao.'</td>';
};
?>
Any solution? Thanks. I'm using mysqli to connect to the database.
make a function from the query script and then call it passing the database table name to it as a parameter. You can then re-use this for different tables
function paginate($conexao, $tblname){
$result_p = mysqli_query($conexao, "select count(*) as count FROM ".$tblname);
$row_p = mysqli_fetch_array($result_p);
$quant_resul = 10;
$pagina = 1;
$paginas = ceil($row_p['count'] / $quant_resul);
$result = mysqli_query($conexao, "select * FROM ".tblname." limit 0 , " . $quant_resul);
return $result;
}
<table class="flat-table flat-table-1">
<thead>
<th>Id</th> **//Here i need get tables columns name to make it dinamically for reuse in other tables**
<th>Photo</th>
<th>Title</th>
<th>Description</th>
</thead>
<tbody>
<tr>
<?php
$result = paginate($conexao, 'banner-destaque');
while ($row = mysqli_fetch_object($result)) {
echo
'
//and here i need get all columns values to populate the above column.
<td>'.$row->id.'</td>
<td>'.$row->foto.'</td>
<td>'.$row->titulo.'</td>
<td>'.$row->descricao.'</td>';
};
?>

fetching multiple columns of mysql table and echoing each row

I have this php/html code that echos a column from a mysql table called "tickets".
These are the 3 columns in the table (member_id, ticket_id, ticket_result).
I want to be able to grab the info from the other columns in a specific row and echo that with the foreach loop. I just don't know how I would be able to do that because you can only have 1 array in a foreach loop so if I was to make add this line to the PHP Code I don't see how I could echo it in the foreach loop.
$me3 = array();
$me2[] = $row->ticket_result;
PHP Code:
public function tickets() {
$this->db_connection = new mysqli('', '', '', '');
$sql = "SELECT ticket_result
FROM tickets
WHERE member_id = '1'";
$query = $this->db_connection->query($sql);
$me2 = array();
while ($row = $query->fetch_object()) {
$me2[] = $row->ticket_result;
}
return $me2;
}
}
HTML Code:
<?php $me2 = $classLogin->tickets(); ?>
<?php foreach($me2 as $value) { ?>
<table>
<thead>
<th>Result</th>
<th>ID</th>
</thead>
<tr>
<td><?php echo $value; ?> </td>
<td> </td>
<?php } ?>
</tr>
</table>
You're only selecting one column of your table:
$sql = "SELECT ticket_result FROM tickets WHERE member_id = '1'";
Your statement should look like this:
$sql = "SELECT member_id, ticket_id, ticket_result FROM tickets WHERE member_id = '1'";
Or:
$sql = "SELECT * FROM tickets WHERE member_id = '1'";
Then you can retrieve your data with this:
while ($row = $query->fetch_object()) {
$me2[$row->ticket_id]['ticket_result'] = $row->ticket_result;
$me2[$row->ticket_id]['member_id'] = $row->member_id;
}
So you'll have an array ($me2) that contains keys according to your ticked_ids and each key is an array with the keys ticket_result and member_id which contain that data from your db.
Then you can implement your foreach like this:
foreach($me2 as $key => $value) {
echo $key;
echo $value['ticket_result'];
echo $value['member_id'];
}
Also, if the HTML you have to print is not that much, I suggest you better use echo and concatenate a string withing a single php clause rather than opening and closing multiple php tags for every little php code you have to execute, your code would look like this:
<?php
$me2 = $classLogin->tickets();
echo
'<table>
<thead>
<th>Result</th>
<th>ID</th>
</thead>';
foreach($me2 as $key => $value) {
echo
'<tr>
<td>'.$value['ticket_result'].'</td>
<td>'.$value['member_id'].'</td>
</tr>';
}
echo '</table>';
?>

retrieving and echoing multiple values from mysql column

I have created these 3 columns in my mysql table so I can have a list of each users transactions.
ticket_date, ticket_num, ticket_result
I also created a function to echo the value in those columns and it worked successfully.
function.php:
$sql = "SELECT *
FROM members
WHERE user_id = '{$_SESSION['user_id']}'";
$query = $this->db_connection->query($sql);
while ($row = $query->fetch_object()) {
global $me, $me2, $date;
$me = $row->ticket_num;
$me2 = $row->ticket_result;
$date = $row->ticket_date;
}
transactions.php
<table class="table">
<thead>
<th>Date</th>
<th>Ticket ID</th>
<th>Result</th>
</thead>
<tr>
<td><?php echo $date; ?> </td>
<td><?php echo $me; ?> </td>
<td><?php echo $me2; ?> </td>
</tr>
</table>
My problem now is that if a user has more than one transaction how would I be able to echo each value from a particular column separately. I am trying to echo each transaction into a .
Would I be able to store each value as an array so I could call it like this?
$row->ticket_num['0']
EDIT: I meant to ask how can I store the transactions into their respective columns. Such as storing more than one $ticket_date that apply to each transaction. Could I store information into the columns as an array so I can call each transaction using the array pointer?
I think the best thing to do, would be not to use global variables for this, unless there is any reason that your function can't return this data, i.e. it's returning something else. You could have something like this in your function.php:
$sql = "SELECT *
FROM members
WHERE user_id = '{$_SESSION['user_id']}'";
$query = $this->db_connection->query($sql);
$return = array();
while ($row = $query->fetch_object()) {
array_push($return, array($row->ticket_num, $row->ticket_result, $row->ticket_date ));
}
return $return
Then you can do this in your transactions.php:
<table class="table">
<thead>
<th>Date</th>
<th>Ticket ID</th>
<th>Result</th>
</thead>
<?php
$ticket = Whatever_Function();
foreach($ticket as $t){
echo"<tr> <td> ".$t[0]." </td><td>".$t[1]."</td><td>".$t[2]."</td></tr>";
}
?>
</table>
Edit
In relation to your additional question in the comments, a database structure like this should be set up:
By doing this, you are separating it, so that every table belongs to one thing or action. These can then be related to each other using an SQL Join like this:
SELECT * FROM Transactions tr
JOIN Users u ON u.UID = tr.UID
JOIN Tickets ti ON ti.TID = tr.TID
By looking at the above SQL code snippet, you should be able to see how it matches up the columns on the different tables. This creates one big virtual table that you can then search for stuff with, where their column names prepended with their given pseudonyms.
So if you wanted to get the email address of everyone that bought the ticket whose price was over £20, even though the tables you need aren't directly connected you could do:
SELECT u.email FROM Transactions tr
JOIN Users u ON u.UID = tr.UID
JOIN Tickets ti ON ti.TID = tr.TID
WHERE ti.Price > 20
Do something like this:
global $me, $me2, $date;
while ($row = $query->fetch_object()) {
$me[] = $row->ticket_num;
$me2[] = $row->ticket_result;
$date[] = $row->ticket_date;
}
transactions.php
<table class="table">
<thead>
<th>Date</th>
<th>Ticket ID</th>
<th>Result</th>
</thead>
<?php foreach($me as $k => $m){
echo "<tr>";
echo "<td>".$date[$k]."</td>";
echo "<td>".$m."</td>";
echo "<td>".$me2[$k]."</td>";
echo "</tr>";
?>
</table>

Only last result of an array showing in html table (php, mysql)

TEST SITE Look here to see code in action
I have two arrays which when echo'd show exactly what i want it to (look at the test site). I'm trying to get them both into a html table but it is only showing the last entry. I have shoved the entire array code into the table and it works fine (although there all in the same row and not separated) but as it is being used in a html email i'm not sure if this will be safe? I'm sorry if this is a really simple fix i'm new to php/mysql so the simple things seem impossible at the moment. I also know i could no doubt combine the two arrays but im on a KISS mantra at the moment and this is the easiest for me to understand. Any help would be appreciated. Thanks.
<?php
//Get Order Codes
foreach ($ids as $id) {
$sqlcode = "SELECT od_code FROM tbl_order_code WHERE pd_id = $id LIMIT 1";
$result = mysql_query($sqlcode);
while($row = mysql_fetch_assoc($result)) {
$codes['codes'] = $row['od_code'];
}
echo "".$codes['codes']."<br />";
}
//Get Product Name
foreach ($ids as $id) {
$sqlname = "SELECT pd_name FROM tbl_product WHERE pd_id = $id";
$result = mysql_query($sqlname);
while($row = mysql_fetch_assoc($result)) {
$names['names'] = $row['pd_name'];
}
echo "".$names['names']."<br />";
}
?>
<table width='550' border='1' align='center' cellpadding='5' cellspacing='1'>
<tr>
<td>Description</td>
<td>Code</td>
</tr>
<tr>
<td> <?php echo "". $names['names'].":"."<br>"?> </td>
<td> <?php echo "". $codes['codes']."<br>"?> </td>
</tr>
</table>
A better solution
Change your logic so that you only use one SQL query and make use of a join.
SELECT p.pd_name,
oc.od_code
FROM tbl_product p
LEFT JOIN tbl_order_code oc ON oc.pd_id = p.pd_id
WHERE p.pd_id = $id
So this should be the following using PDO:
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
$stmt = $dbh->prepare("
SELECT p.pd_name,
oc.od_code
FROM tbl_product p
LEFT JOIN tbl_order_code oc ON oc.pd_id = p.pd_id
WHERE p.pd_id = ?");
if ($stmt->execute(array($id))) {
while ($row = $stmt->fetch()) {
// print out table rows here
}
}
Immediate fix (yuck)
This should solve your immediate problem, but there is a much better way of doing this.
<?php
foreach ($ids as $id) {
$sqlcode = "SELECT od_code FROM tbl_order_code WHERE pd_id = $id LIMIT 1";
$result = mysql_query($sqlcode);
$codes = array();
while($row = mysql_fetch_assoc($result)) {
$codes[] = $row['od_code'];
}
//Get Product Name
foreach ($ids as $id) {
$sqlname = "SELECT pd_name FROM tbl_product WHERE pd_id = $id";
$result = mysql_query($sqlname);
$names = array();
while($row = mysql_fetch_assoc($result)) {
$names[] = $row['pd_name'];
}
}
?>
<table width='550' border='1' align='center' cellpadding='5' cellspacing='1'>
<tr>
<td>Description</td>
<td>Code</td>
</tr>
<?php foreach($names as $key => $name): ?>
<tr>
<td> <?php echo $name .":"."<br>"?> </td>
<td> <?php echo $codes[$key]."<br>"?> </td>
</tr>
<?php endforeach; ?>
</table>
$names['names'][] = $row['pd_name'];
<td> <?php foreach($names['names'] as $name){ echo "". $name.":"."<br>" } ?> </td>
Or as suggested in comments:
while($row = mysql_fetch_assoc($result)) {
$names['names'] = $row['pd_name'];
$codes['codes'] = $row['pd_code'];
?>
<tr>
<td> <?php echo "". $names['names'].":"."<br>"?> </td>
<td> <?php echo "". $codes['codes']."<br>"?> </td>
</tr>
<?php } ?>
Please try to use PDO instead for interacting with mysql http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
You have to iterate through the array within the table, the same way you do it above the table-tags.
you are using
foreach($ids as $id)
make table to be populated inside foreach
or else use 2d array $name and $codes and count the array size and loop your table structure for count no of times

Categories