Im sorry if this has been answered before but I am new to PHP and MySQL and I can't figure this out.
Pretty much every time I alter my code to include an array I get a fatal error. What I am trying to do is display all the data in 3 columns from my table.
I have my site set up where you log in and I store that user's name as a "code" in a session. I have a table that has multiple user form entries that are differentiated by the user's code because in my form, I grab the code as a hidden field and add it to the entry in the table.
So far I have been able to isolate those entries by the users code, in one column I have the sum of all of the user's numerical data and I am able to echo this as a total.
I want the other 3 columns to display all the values in their columns and for each value have a line break in between them. And I am trying to print or echo these results in specific parts on a confirmation page.
I have seen examples with PDO using fetch_all and other examples of storing arrays but I can't seem to figure it out with my existing code.
Here is my existing code:
<?php
$user = *****;
$pass = *****;
$dbh = new PDO('mysql:host=localhost;dbname=*****', $user, $pass);
$stmt = $dbh->prepare("SELECT sum(price),part_number,location,price FROM products WHERE code = :usercode");
$stmt->bindParam(':usercode', $_SESSION['MM_Username']);
if ($stmt->execute()) {
$user = $stmt->fetch(PDO::FETCH_ASSOC);
}
?>
And here is where I want to display the results:
<table style="margin:0 auto;" cellspacing="7" width="100%">
<tbody>
<tr>
<td><?php echo $user['part_number']; ?></td><!--all column values-->
<td><?php echo $user['location']; ?></td><!--all column values-->
<td><?php echo $user['price']; ?></td><!--all column values-->
<td><?php echo "Total:", $user['sum(price)']; ?><br></td><!--this is ok-->
</tr>
</tbody>
</table>
Try like this:
<table style="margin:0 auto;" cellspacing="7" width="100%">
<tbody>
if ($stmt->execute()) {
while($user = $stmt->fetch( PDO::FETCH_ASSOC )){
<tr>
<td><? echo $user['part_number']; ?></td><!--all column values-->
<td><? echo $user['location']; ?></td><!--all column values-->
<td><? echo $user['price']; ?></td><!--all column values-->
<td><? echo "Total:", $user['sum(price)']; ?><br></td><!--this is ok-->
</tr>
}
}
</tbody>
</table>
There are a few things in your question that jumped out at me.
It looks like you're attempting to display both raw data (each row) and aggregate data (the sum of prices). It can be simpler to fetch the information separately instead of in the same request.
You had mentioned fetch_all in PDO, but the method is fetchAll.
Instead of working with PDO within the HTML (like iterating through while calling fetch), write code so that you're simply iterating over an array.
Based on your description of the problem, it sounds like you want to separate the total price from the raw data, so you can reduce your table down to three columns and use the table footer to show the total price.
Based on those, I have the following solution that
Separates the calls to get data into descriptive functions
Use money_format to better display prices
Removes any database-specific manipulation from the view itself.
<?php
function getTotalPriceForUser(PDO $database_handler, $user_code)
{
// If no rows are returned, COALESCE is used so that we can specify a default
// value. In this particular case, if there aren't any products that would
// match, we'd still get a result with a value of 0.
$sql = 'SELECT COALESCE(SUM(price), 0) FROM products WHERE code = ?';
$stmt = $database_handler->prepare($sql);
$stmt->execute(array($user_code));
// This fetches the first row of the result; the result is given as an array with numerical keys.
$result = $stmt->fetch(PDO::FETCH_NUM);
// [0] refers to the first column
return $result[0];
}
function getProductsForUser(PDO $database_handler, $user_code)
{
$sql = 'SELECT part_number, location, price FROM products WHERE code = ?';
$stmt = $database_handler->prepare($sql);
$stmt->execute(array($user_code));
// fetchAll returns all rows, with each row being an associative array (where part_number, location and price are the keys)
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// Set up the database information
$user = '*****';
$pass = '*****';
$dbh = new PDO('mysql:host=localhost;dbname=*****', $user, $pass);
// money_format to use the below money formatting; this makes sure there's a dollar sign to represent USD, for example
setlocale(LC_MONETARY, 'en_US.UTF-8');
// Store $_SESSION['MM_Username'] in a local variable
$user_code = $_SESSION['MM_Username'];
// Get the list of products associated with this user code
$products = getProductsForUser($dbh, $user_code);
// Get the total cost of the products
$total_cost = getTotalPriceForUser($dbh, $user_code);
?>
<table style="margin:0 auto;" cellspacing="7" width="100%">
<thead>
<tr>
<th>Part Number</th>
<th>Location</th>
<th>Cost</th>
</tr>
</thead>
<tfoot>
<tr>
<td style="text-align: right" colspan="2">Total:</td>
<td style="text-align: right; border-top: 1px solid #999"><?= money_format('%.2n', $total_cost) ?></td>
</tr>
</tfoot>
<tbody>
<?php foreach($products as $product): ?>
<tr>
<td><?= $product['part_number'] ?></td>
<td><?= $product['location'] ?></td>
<td style="text-align: right"><?= money_format('%.2n', $product['price']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
Change to this
<? echo
to
<?php echo
Try this:
...
$keys = array_keys($user);
foreach ($keys as $k) :
?>
<td><?= $user[$k]?></td>
<?php endforeach?>
<table>
<tbody>
if ($stmt->execute()) {
while($user = $stmt->fetch( PDO::FETCH_ASSOC )){
<tr>
<td><?php echo $user['part_number']; ?></td><!--all column values-->
<td><?php echo $user['location']; ?></td><!--all column values-->
<td><?php echo $user['price']; ?></td><!--all column values-->
<td><?php echo "Total:", $user['sum(price)']; ?><br></td><!--this is ok-->
</tr>
}
}
</tbody>
</table>
Related
I am wanting to match my user_id column from my announcements table to the id column in my users table. I then want to get the username from the users table where the id's match.
I initially had the following query
if ($announcements_stmt = $con->prepare("SELECT * FROM announcements"))
I am getting the following error with my current code..
Warning: mysqli_stmt::bind_result(): Number of bind variables doesn't match number of fields in prepared statement in
Which I know what this means, but do I need to add in every column table from my users table for this to work or is there another way to do this? If I do need to add all of the columns as variables in my bind_result, does it matter which order I put them in? Announcements first or users or vise versa?
if ($announcements_stmt = $con->prepare("SELECT * FROM announcements
INNER JOIN users
ON announcements.user_id = users.id")) {
$announcements_stmt->execute();
$announcements_stmt->bind_result($announcements_id,
$announcements_user_id, $announcements_messages, $announcements_date);
if (!$announcements_stmt) {
throw new Exception($con->error);
}
$announcements_stmt->store_result();
$announcements_result = array();
?>
Current Announcements
<table>
<tr>
<th>ID</th>
<th>Username</th>
<th>Message</th>
<th>Date</th>
</tr>
<?php
while ($row = $announcements_stmt->fetch()) {
?>
<tr>
<td><?php echo $announcements_id; ?></td>
<td><?php echo $announcements_username; ?></td>
<td><?php echo $announcements_messages; ?></td>
<td><?php echo $announcements_date; ?></td>
</tr>
<?php
}
?>
}
update..
if ($announcements_stmt = $con->prepare("SELECT announcements.id, announcements.user_id, announcements.messages, announcements.date, users.username FROM announcements
INNER JOIN users
ON announcements.user_id = users.id")) {
$announcements_stmt->execute();
$announcements_stmt->bind_result($announcements_id,
$announcements_user_id, $announcements_messages, $announcements_date, $announcements_username);
if (!$announcements_stmt) {
throw new Exception($con->error);
}
$announcements_stmt->store_result();
$announcements_result = array();
?>
Current Announcements
<table>
<tr>
<th>ID</th>
<th>Username</th>
<th>Message</th>
<th>Date</th>
</tr>
<?php
while ($row = $announcements_stmt->fetch()) {
?>
<tr>
<td><?php echo $announcements_id; ?></td>
<td><?php echo $announcements_username; ?></td>
<td><?php echo $announcements_messages; ?></td>
<td><?php echo $announcements_date; ?></td>
</tr>
<?php
}
?>
}
</table>
<?php
}
}
The warning indicates when you are binding the result fields into variables, the number of variables does not match the number of fields in the result set:
$announcements_stmt->bind_result($announcements_id, $announcements_user_id, $announcements_messages, $announcements_date, $announcements_username);
The easy way around this is to always specify the fields in the SELECT statement (just an example):
SELECT t1.id, t1.user_id, t1.messages, t1.date, t2.username
Instead of:
SELECT *
<table border="1" width="500">
<tbody>
<tr>
<th>ProFileID</th>
<th>CogID</th>
<th>FileValue</th>
<th> Count </th>
<?php
$sql="Select * From idtable"; // Read idtable
$result=mysql_query($sql); // Query sql
$num=mysql_num_rows($result); // Check record
if($num>0){ // If record > 0
$count=1; //
while($recordset=mysql_fetch_assoc($result)){ // loop
?>
<tr>
<td align="center"><?php echo $count; ?></td>
<td><?php echo $cogid = $recordset['CogID']; ?></td>
<td><?php echo $FileValue = $recordset['FileValue']; ?></td>
<td><? $url = "https://s3-ap-southeast-1.amazonaws.com/cloudpoc2/".$cogid."/Contacts/contactsversion3/".$FileValue."";
//example "https://s3-ap-southeast-1.amazonaws.com/cloudpoc2/us-east-1%3Ab9b09e99-5921-494a-b5a7-54f289131eaa/Contacts/contactsversion3/Contacts_1437450598237.txt";
$getText = file_get_contents("$url", true);
$Contact = substr_count($getText ,"FIRSTNAME");
echo $countupdate = $Contact; ?>
</tr>
<?
$count+=1; // Increase count +1
}
}
?>
</tbody>
<?php // UPDATE TO DATABASE
$updatecount = "INSERT INTO counttable (ProfileID,Count,Timestamp)
VALUES('','$countupdate','')";
mysql_query($updatecount);
?>
**I want to update count to phpmyadmin Table name is Countable I have 2 data but it show only one data i don't know what happen ** Some on kind please help me
This my pic
You do an update after while loop is over. After loop is over $updatecount stores the last value of $Contact. If you want to update table on each iteration of while loop, move your update query in the loop:
while($recordset=mysql_fetch_assoc($result)) { // loop
// do something here
$updatecount = "INSERT INTO counttable (ProfileID,Count,Timestamp) VALUES('','$countupdate','')";
mysql_query($updatecount);
}
I have a simple issue I cannot figure out. I am trying to get the id of the record setup as a link to go to a second page that updates the record. I have the update working when I click on update it takes me to the record. I want the id to do the same.
<html>
<?php
require_once("../db_connect.php");
$stmt = $db->prepare("SELECT * FROM Users");
$stmt->execute();
?>
<?php while( $row = $stmt->fetch(PDO::FETCH_ASSOC) ) { ?>
<table bgcolor=F2F2F2 width=1080 border='2'table-layout: fixed >
<br>
<tr>
<th>Id</th>
<th>Update</th>
<th>First Name</th>
<th>Last name</th>
<th>Address</th>
<th>Bio</th>
</tr>
<tr>
<?php echo "<td>
<a href='../update.php?id=" . $row['id'] . "'>ID</a></td>"?>
<?php echo "<td>
<a href='../update.php?id=" . $row['id'] . "'>Update</a></td>"?>
<td><?php echo $row['First Name']; ?></td>
<td><?php echo $row['Last Name']; ?></td>
<td><?php echo $row['Address']; ?></td>
<td><?php echo $row['Bio']; ?></td>
</tr>
<?php } ?>
</table>
</body>
</html>
In general, it is a good practice to put duplicated content into a function or variable and then call it when needed, to improve code readability & to save time/space.
I have also noticed many people struggling with new syntax so I have split the "one-liners" and left comments explaining how does new syntax works.
function col_gen($slug,$id=''){
return (!empty($id))? // If ID parameter exist and not empty generate column with a link
'<td>'.$slug.'</td>': //else
'<td>'.$slug.'</td>';
}
And then, in your case, you can run this function inside a loop:
....
foreach($row as $k=>$slug){
echo ($k==='id')? //if key equals "id"
col_gen($slug,$slug) // Output column for ID
.col_gen('Update',$slug) // Output column for keyword Update
:col_gen($slug); //else output just column with the slug
/**
* Learn one-line PHP, you will love it, once you understand it...
* Full Example Above:
* echo ($k==='id') ? col_gen($slug,$slug).col_gen('Update',$slug):col_gen($slug);
**/
}
To create a dynamic table within php, I set the variable $count from a query, which counts the rows in specific table. Then I would like to create a table with the exact number of rows as a html table:
for($i=1;$i=<$count;$i++){
echo"<tr><td>$name</td><td>$rights</td></tr>";
}
That's the way i want the table to be displayed. But everytime the for-loop is called, the values of $name and $rights should be taken from the database-table. But how should i handle this? I thought about a simple query selecting the name from the line where ID equals i. But then i remembered that always when i delete an entry from the table there will be gaps.
For example when there 3 entries and i delete the second one. There just are 2 entries; so the name of the second row, which ID is 3, will never be selected. Is there any way of handling this problem in an appropriated way?
You wouldnt use a for you would use a while or a foreach with the results from the query.
<?php
$db = new PDO($dsn, $user, $pass);
$stmt = $db->query('SELECT id, rights FROM the_table');
?>
<table>
<thead>
<tr>
<th>Id</th>
<th>Rights</th>
</tr>
</thead>
<tbody>
<?php if($stmt !== false): ?>
<?php foreach( $stmt as $row): ?>
<tr>
<td><?php echo $row['id'] ?></td>
<td><?php echo $row['rights'] ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
A user chooses a value from a select box which is then passed via a form to another page which should show the mysql record of that selection. This is not showing any results, however the value is definitely being passed as it can be echoed out.
<?php
include("top.php");
$db = getConnection();
$eventID = $_POST['eventID'];
echo $eventID;
$queryEvent = $db->query("SELECT * FROM projectEvent WHERE eventID = '$eventID'");
$queryEvent->setFetchMode(PDO::FETCH_ASSOC);
$record = $queryEvent->fetchALL();
?>
<form name="form1" id="form1" method="post" action="deleteOpen.php">
<p> are you sure you want to delete the following Open Day? </p>
<table width="200" cellpadding="0" cellspacing="0">
<tr>
<th scope="row">eventID</th>
<td><?php echo $record -> eventID; ?></td>
</tr>
<tr>
<th scope="row">propertyID</th>
<td><?php echo $record -> propertyID; ?></td>
</tr>
<tr>
<th scope="row">eventDate</th>
<td><?php echo $record -> eventDate; ?></td>
</tr>
<tr>
<th scope="row">eventTime</th>
<td><?php echo $record -> eventTime; ?></td>
</tr>
<tr>
<th scope="row">eventDescription</th>
<td><?php echo $record -> eventDescription; ?></td>
</tr>
</table>
Can anyone suggest why the values are not shown in the table?
Thanks
to show data you shouldn't use POST method but GET instead.
either escape your values with PDO::quote or use prepared statements with prepare/execute instead of query()
if you are using ASSOC mode - why you are accessing them as a object properties?
Moreover, you actually have a nested array, but accessing it as a single object. if you don't need an array - don't use fetchAll() then
ALWAYS have error_reporting(E_ALL); in your scripts to see these silly mistakes.
You can concatenate the variable separately like this :
$queryEvent = $db->query("SELECT * FROM projectEvent WHERE eventID = ".$eventID.")";
Normally I do a little bit different of a method. It may not point out the problem but I think it will solve it. I usually dont use variables inside of quotes, but try below.
$sql = sprintf("SELECT * FROM projectEvent WHERE eventID = '%s'", $eventID);
$queryEvent = $db->query($sql);