I'm trying to fetch all records from my table on my site, I have the following
$sth = $conn->prepare("SELECT * FROM directory WHERE user_active != ''");
$sth->execute();
/* Exercise PDOStatement::fetch styles */
$result = $sth->fetch(PDO::FETCH_ASSOC);
foreach ($sth->fetchAll(PDO::FETCH_ASSOC) as $result) {
echo $result[First_Name];
}
Only its not returning all records, only my first, Can anybody see where I'm going wrong?
You need to use a loop:
while ($result = $sth->fetch(PDO::FETCH_ASSOC)) {
echo $result[First_Name];
echo ' ' . $result[Surname];
}
Or you could use fetchAll method:
foreach ($sth->fetchAll(PDO::FETCH_ASSOC) as $result) {
echo $result[First_Name];
echo ' ' . $result[Surname];
}
And Note: If First_Name and Surname are not constants, then you should use the string as the key name.
$result['First_Name'] and $result['Surname']
Well, you only call $sth->fetch once. You need to loop over the results.
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
echo $row['First_Name'] . ' ' . $row['Surname'] . "\n";
}
Also don't call array string indexes without braces. This way PHP checks if the key is a CONSTANT, then casts it to string. This is just bad practice and might lead to unexpected bahavior.
If this returns only one row, you probably have only one row in the database (or the result set). Show us more code!
Related
i have a little problem, i have a database with 2 tables, users and comments and i need to print the result with pdo.
if i try this code, everything works great:
$stmt = $dbConnection->prepare("SELECT comment_text, username FROM users, comments WHERE users.user_id = comments.user_id");
$stmt->execute();
$stmt->fetch(PDO::FETCH_ASSOC);
foreach ($stmt as $row) {
echo $row['comment_text'] . "<br>By " . $row['username'] . "<br>";
}
But if i try to add a variable which get the result of fetch i get a totally different result with only 2 rows and only the first letter of the value...
$stmt = $dbConnection->prepare("SELECT comment_text, username FROM users, comments WHERE users.user_id = comments.user_id");
$stmt->execute();
$comment = $stmt->fetch(PDO::FETCH_ASSOC);
foreach ($comment as $row) {
echo $row['comment_text'] . "<br>By " . $row['username'] . "<br>";
}
if i try this code, everything works great:
it is not.
this way you are losing the very first comment. So it should be just
$stmt->execute();
foreach($stmt as $row )
{
echo $row['comment_text']."<br>By ".$row['username']."<br>" ;
}
in case you want to save the result in array, you have to use the appropriate function for that:
$stmt->execute();
$comments = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($comments as $row )
{
echo $row['comment_text']."<br>By ".$row['username']."<br>" ;
}
while fetch() is getting you only one record, fetchAll() is doing what the name suggests
Both your samples aren't functionning properly :
In the first one you loop over every row except the first row, for which you did a fetch, and then did nothing with this first row.
In the second one you loop over every field of the first row, which produce some unexepected output.
I get the following error:
Invalid argument supplied for foreach()
for the following code:
<?php
$connection=mysqli_connect(/*hostname*/"localhost",
/*username*/"u",
/*password*/"p",
/*database name*/"d");
try {
// Setting the query and runnin it...
$sql = "SELECT * FROM `table` WHERE `category` = 5 ORDER BY 3";
$result = $connection->query($sql);
// Iterating over the data and printing it.
foreach($result as $row) {
echo $row['rowa']. ' - '. $row['rowb']. ' - '. $row['rowc']. ' - '. $row['rowd']. ' - '. $row['rowe'].'<br />';
}
// Closing the connection.
$connection = null;
}
// Catching it if something went wrong.
catch(PDOException $e) {
echo $e->getMessage();
} ?>
How do I fix this error and is there anything else wrong with the coding?
Basically, your usage of foreach() is correct. However, it won't work with results returned by a SQL query.
Instead, you'll have to use another loop, e.g. something like this:
while ($row = function_taking_one_result($result)) {
// your own handling of $row
}
For function_taking_one_result() you've got a few built-in function calls handling the returned results in different ways (see documentation).
What you're most likely looking for is mysqli_fetch_row() which will return a PHP array using the column names as keys and the row's data as values. This function will return FALSE once there aren't any further results (and therefore leave the loop).
Use it in this way:
foreach(mysqli_fetch_array($result) as $row) {
echo $row['rowa']. ' - '. $row['rowb']. ' - '. $row['rowc']. ' - '. $row['rowd']. ' - '. $row['rowe'].'<br />';
}
EDIT:
$result = mysqli_query($connection,$sql);
if($result)
{
foreach(mysqli_fetch_array($result) as $row) {
echo $row['rowa']. ' - '. $row['rowb']. ' - '. $row['rowc']. ' - '. $row['rowd']. ' - '. $row['rowe'].'<br />';
}
}else{
echo "QUERY IS NOT OK";
}
The query() method returns an resource identifier not ARRAY. so you cant loop over non array thing. foreach loop can be used only for Arrays.
After running the query you need to fetch the data in array and then try running it on loop.
Its better if you use while() loop for db arrays.
for ex:
$sql = "SELECT * FROM `table` WHERE `category` = 5 ORDER BY 3";
$qry = $connection->query($sql); //Runs the query but wont fetch RESULT
// Iterating over the data and printing it.
while($row=$qry->fetch_array()) {
//or $qry->fetch_assoc(), $qry is the variable used to execute query. check above line
echo $row['rowa'].'-'. $row['rowb'].'-'.$row['rowc'].'-'.$row['rowd'].'-'.$row['rowe'].'<br />';
}
I want to run a query using PDO, based on data in the URL paramater (yes, I know that this is prone to attacks, but its internal code for a utility).
$user = 'USER';
$pass = 'PASSWORD';
$dsn = 'mysql:dbname=PRODUCTS;host=HOST';
try {
$productDB = new PDO($dsn, $user, $pass);
$productDB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
$msg = 'PDO ERROR' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
die($msg);
}
if(isset($_GET['cat']))
{
$cat = $_GET['cat'];
print "cat = $cat <br>";
$products = $productDB->prepare('SELECT * FROM products WHERE cat_id LIKE ?');
$products->execute(array($cat));
$rows = $products->rowCount();
print "$rows rows returned";
?>
<table border="1">
<tr>
<td>product_id</td>
<td>product_name</td>
</tr>
<?php
foreach ($products->fetchAll() as $row) {
$id = $row['product_id'];
$product_name = $row['product_name'];
print "<tr>";
print "<th scope=\"row\"><b>$id</b></th>";
print "<td> $product_name </td>";
print "<tr>";
}
print "</table>";
}
?>
When I run this code, it prints the correct number of rows depending on the query, but does not populate the table.
I have also tried replacing the prepare and execute lines with:
$products = $productDB->query("SELECT * FROM products WHERE cat_id LIKE $cat");
Which returns the correct row count, but doesn't otherwise help.
And finally, I've tried replacing the foreach line with something like:
$rows = $products->fetchAll();
foreach ($rows as $row) {
My attempts to do the same with a fixed query all work fine, but I am having trouble working out how to place a variable element in a query, and then iterate over the results.
You're not doing anything to store the result:
$products->execute(array($cat));
needs to go in a variable:
$result = $products->execute(array($cat));
Then, instead of calling $products->fetchAll(), use $results->fetchAll():
foreach ($result->fetchAll() as $row)
I find it easier to use a $query variable (for prepare, etc) and then get the result into something like $result or $product. Makes the code a bit easier to read.
Try this (If I understood correctly) :
$products = $productDB->prepare("SELECT * FROM products WHERE cat_id LIKE :cat");
// Now, you can either do this :
$products->bindParam('cat', '%'.$cat.'%');
$products->execute();
// or you can call execute with an associative array of your parameterized query.
$products->execute(array('cat' => '%'.$cat.'%'));
// Then, get all the results like this :
$rows = $products->fetchAll();
foreach ($rows as $row) {
// Do work here ..
}
// Or, like this :
while ($row = $products->fetch(PDO::FETCH_ASSOC)) {
// Do work here ..
}
I personaly prefer the while, because you don't fetch the whole query in one var, reducing the amount of memory needed.
I also recommend you to use the FETCH_* parameter, to get only the kind of array you want.
By the way, you need to know that rowCount should not be used to count the rows returned by a SELECT. As said by php.net :
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.
I'm currently updating my app by switching to PDO. I have the following code:
$stmt = $db->prepare("select * from `product` where productid in (:productidLst)");
$stmt->bindParam(":productidLst",$productidLst, PDO::PARAM_INT);
$stmt->execute();
The var $productidLst is 1,2 after the above code I would like to use the PDO equivalent of this:
while($rs=mysql_fetch_assoc($res)){
$rs['qty']=$_SESSION['basket'][$rs['productid']];
$rs['total'] += $rs['qty']*$rs['price'];
$total += $rs['total'];
$a[] = $rs;
}
I have tried numerous combinations but not been successful so any help with this would be appreciated (in the 2nd code block $res was the sql). Secondly I have set the Parameter $productidLst to INT is this correct or should it be a string?
--------------------UPDATE 1----------------------------------------------------
I have tried the following code:
$stmt = $db->prepare("select * from `product` where productid in (:productidLst)");
foreach ($stmt->execute(array(':productidLst' => $productidLst)) as $row)
{
$total += $row['total'];
}
Which returns: Invalid argument supplied for foreach() error
The standard documentation in the PHP manual is usually pretty helpful. There is an example of executing a for loop with PDO in the PHP manual, PDO Details.
function getFruit($conn) {
$sql = 'SELECT name, color, calories FROM fruit ORDER BY name';
foreach ($conn->query($sql) as $row) {
print $row['name'] . "\t";
print $row['color'] . "\t";
print $row['calories'] . "\n";
}
}
With a few changes, the example can be made to use a prepared statement.
function getFruit($conn) {
$query = $conn->prepare('SELECT name, color, calories FROM fruit WHERE kind=:kind ORDER BY name');
$query->execute(array(':kind' => 'drupe'));
// alternatively you could use PDOStatement::fetchAll() and get rid of the loop
// this is dependent upon the design of your app
foreach ($query as $row) {
print $row['name'] . "\t";
print $row['color'] . "\t";
print $row['calories'] . "\n";
}
}
You can also use a while loop and PDOStatement::fetch to get each row.
function getFruit($conn) {
$query = $conn->prepare('SELECT name, color, calories FROM fruit WHERE kind=:kind ORDER BY name');
$query->execute(array(':kind' => 'drupe'));
// alternatively you could use PDOStatement::fetchAll() and get rid of the loop
// this is dependent upon the design of your app
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
print $row['name'] . "\t";
print $row['color'] . "\t";
print $row['calories'] . "\n";
}
}
The PHP manual remains quite helpful in providing all the necessary information to create the latter two versions.
Explanation of the last version: assuming $conn is a valid PDO object. $conn->prepare($sql) returns a PDOStatement object if successful, false on failure OR an exception based on your error handling. So, assuming success we would want to actually get the data from the object. We can use $query->fetch() in a loop or $query->fetchAll() to get the data dependent upon your app. Passing in the class constant PDO::FETCH_ASSOC will return, you guessed it, an associative array of data.
Functionally, the foreach and while implementations are equivalent. Conceptually, a foreach is more appropriate, as a while loop has connotations of looping while a static condition holds, whereas foreach loops over elements of a collection. Read "Differences between a while loop and a for loop in PHP?" for part of the story.
Be sure to read the php.net reference on PDO
You should be using PDOStatement::fetch() to fetch the row. It fetches (by default) both numerically and associatively. You can change that as well.
With your code:
while($rs=$stmt->fetch()){
$rs['qty']=$_SESSION['basket'][$rs['productid']];
$rs['total'] += $rs['qty']*$rs['price'];
$total += $rs['total'];
$a[] = $rs;
}
Manual Reference.
Basically what I'm trying to achieve is go through an array and do a query based on that data - e.g. array of names bob, bill, ben and query a database table based on all of the items in the array - so SELECT * FROM table WHERE name="$name".
The code I have is:
<?php
session_start();
$array = $_SESSION['basket'];
foreach ($array = $_SESSION['basket'] as $value);
$query = "SELECT * FROM catalogue WHERE plantname='$value'";
$result = mysql_query($query) or die("Query failed : " . mysql_error());
echo "<table>\n";
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
echo "\t<tr>\n";
foreach ($line as $col_value) {
echo "\t\t<td>$col_value</td>\n";
}
echo "\t</tr>\n";
}
echo "</table>\n";
?>
but this is only displaying the last item it should be picking out of the query, any help is much appreciated.
The problem is with this line
foreach ($array = $_SESSION['basket'] as $value);
$query = "SELECT * FROM catalogue WHERE plantname='$value'";
First is the semicolon - it shouldn't be there. Also notice that you have no { } around your foreach statement, so you build a query for each item in your session variable, but execute it only for the last one.
To get everything for all the possible $values, which is what I think you're trying to do, you want something like this:
SELECT * FROM catalogue WHERE plantname IN ('value1', 'value2')
Which can be accomplished with something like:
$query = "SELECT * FROM catalogue WHERE plantname IN ('" . implode($array, "', '") . "')";
...without hitting the database multiple times.
UPDATED: Moved query outside of loop.
<?php
session_start();
$array = $_SESSION['basket'];
$query = "SELECT * FROM catalogue WHERE plantname IN ('" . implode("', '", $array) . "')";
$result = mysql_query($query) or die("Query failed : " . mysql_error());
echo "<table>\n";
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
echo "\t<tr>\n";
foreach ($line as $col_value) {
echo "\t\t<td>$col_value</td>\n";
}
echo "\t</tr>\n";
}
echo "</table>\n";
?>
There are a number of issues in your code.
Firstly you have already assigned to $array so you only need to do:
foreach($array as $value)
Secondly you shouldn't be running queries inside a loop, as the basket gets bigger the more queries are executed on every page request.
Why not push the row into $_SESSION['basket'] then you can just loop $_SESSION['basket'] to show it rather than running loads of queries, it will make your code execute faster and you'll right less code.
Also be careful with the other answers as they haven't considered security as database input should be escaped.