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 />';
}
Related
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 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!
If I do this in PHP, it works fine and loops as expected:
$rs = mysql_query($sql);
while ($row = mysql_fetch_assoc($rs)){
writeme("UserID: " . $row["UserID"]);
}
But I keep wanting to abstract this out into a function I have called ExecuteQuery:
function ExecuteQuery($sql){
$result = mysql_query($sql);
if ($result) {
if($result != 1){
return mysql_fetch_assoc($result); // return recordset
}
}else{
$message = 'Invalid query: ' . mysql_error() . "<br>";
$message .= 'Whole query: ' . $sql;
echo $message;
die();
}
}
This function works great in 2 out of 3 scenarios:
1- Works great for a query that returns 1 row, and I can access like this:
$rs = ExecuteQuery($sql);
$foo = $rs["UserID"];
2- Works great for a sql statement that returns no records, like an UPDATE or DELETE.
3- But when I try to get back a recordset that returns multiple records, and then loop through it, I get an infinite loop and my browser crashes. Like this:
$rs = ExecuteQuery($sql);
while ($row = $rs){
writeme("UserID: " . $row["UserID"]);
}
How can I modify my while loop so it advances to each new record in the recordset and stops after the last record? I'm sure it's a dumb little thing, but I'm not expert with PHP yet. I'd really like my ExecuteQuery function to be able to handle all 3 scenarios, it's very handy.
try foreach($rs as $row){ instead of while ($row = $rs){
mysql_fetch_assoc() only returns one row of the result. To get the next row, you need to call mysql_fetch_assoc() again. One thing you could do is have your ExecuteQuery function return an array of arrays:
$rows = array();
while ($row = mysql_fetch_assoc($result) !== false) {
$rows[] = $row;
}
return $rows;
Also, you should not use the mysql_* functions as they are deprecated. Try using PDO or mysqli_* instead.
Don't use while, use foreach:
$rs = ExecuteQuery($sql);
foreach ($rs as $row){
writeme("UserID: " . $row["UserID"]);
}
This is pretty straight forward.
EDIT: Updated question and added fourth echo.
Here is PHP code:
<?php
$ratings="3";
$item="Inception";
$query="SELECT * FROM items WHERE item = '". $item ."' LIMIT 1";
echo $query;
echo "<br />";
$result=mysql_query($query);
echo $result;
echo "<br />";
while ($row = mysql_fetch_array($result)) {
$item_id = $row['item_id'];
echo $item_id;
echo "<br />";
}
$query_two = "INSERT INTO ratings (rating, item_id), VALUES (' {$ratings} ', ' {$item_id} ')";
echo $query_two;
$sql = mysql_query($query_two);
mysql_close();
?>
Here is web output with all the echo's:
SELECT * FROM items WHERE item = 'Inception' LIMIT 1
Resource id #7
INSERT INTO ratings (rating, item_id), VALUES (' 3 ', ' ')
How come my $item_id is blank? (third row underneath Resource id)
This part of code produces it:
$result=mysql_query($query);
echo $result;
It shows Resource... because it is of resource type, it's just a sort of special handler for query, it's not like normal type (string or int for example), so it has nothing readable to print.
If you want to print data from query then you must firstly fetch it.
Also note that those mysql_* functions are deprecated, it is discouraged to use them. Note from php manual:
Use of this extension is discouraged. Instead, the MySQLi or PDO_MySQL
extension should be used. See also MySQL: choosing an API guide and
related FAQ for more information. Alternatives to this function
include:
mysqli_query()
PDO::query()
This does not have anything to do with IDs from the database.
This (Result#7) says that this result resource is seventh resource to be created by your php script execution.
Also
$query_two = "INSERT INTO ratings (rating, item_id), VALUES (' {$ratings} ', ' {$item_id} ')";
should be
$query_two = "INSERT INTO ratings (rating, item_id) VALUES (' {$ratings} ', ' {$item_id} ')";
You have comma before VALUES.
Also, it seems that $item_id is blank. Please check DB whether you have data for item = 'Inception'.
Regarding, Result#7 please follow others answers.
The Resource ID is coming from the actual process/object that the MySQL Query is.
to return the result you need:
$row = mysql_fetch_array( $query );
echo $row['item']
You need to do something with the result resource. Try this:
$result=mysql_query($query);
//echo $result;
$result_array = mysql_fetch_assoc( $result );
print_r( $result_array );
EDIT: I see you updated your question.
You should run your item='Inception' query directly in MySQL to confirm that results are what you expect.
You cannot echo the result that simple. You need to fetch the result to for example an array:
while ($row = mysql_fetch_array($query)) {
echo $row['a_column'] . "<br />";
}
or an object:
while ($variable = mysql_fetch_object($query) {
$value = $variable->a_column;
}
echo $value;
There are more ways but this is just two examples
I'm having trouble taking data from a table and using it to replace strings in html text. I need to retrieve the last 4 rows from the table, then using str_replace, automatically create hrefs. So one column is url, one is title, one is description, etc. Then I'll create 4 separate hrefs from each row. What I have so far will work for only the last result. How do I make it work for all 4?
$query = "SELECT * FROM LINKS ORDER BY id DESC LIMIT 4";
if(!$result = mysql_query($query)){
// query failed, handle the error here...
$errors[] = "A fatal error occurred and this page is non-functional at this time!";
trigger_error("Query failed: $query<br /> Due to: " . mysql_error()); // application error
} else {
// query worked
if(!mysql_num_rows($result)){
// no matching rows
$main_content .= "No rows were found!\n";
} else {
// query matched at least one row, use the results from the query here...
$row = mysql_fetch_assoc($result);
$title1 .= $row['title'];
$link1 .= $row['url'];
}
}
//string replace arrays
$placeholders = array('LINK1','LINK2', 'LINK3','LINK4');
$replacevals = array($link1, $link2, $link3, $link4);
//replace the areas of the template with the posted values
$page = str_replace($placeholders,$replacevals,$template);
I'd like to be able to output $title2, $link2, $title3, etc.
Easiest way to do so would be to do something like this:
...
// query worked
if(!mysql_num_rows($result)){
// no matching rows
$main_content .= "No rows were found!\n";
}
else {
$urls_array = Array();
// query matched at least one row, use the results from the query here...
while ($row = mysql_fetch_assoc($result))
{
$urls_array[] = "<a href='" . $row['url'] . "'>" . $row['title'] . "</a>";
}
}
Then you end up with an array of html links set to the $urls_array variable.
Use a loop with mysql_fetch_assoc(). Traditionally, a while loop.
Here's an example derived from the PHP docs:
while ($row = mysql_fetch_assoc($result)) {
echo $row['title'];
}
That should get you started. Welcome to StackOverflow.