I'm stuck on this problem for a while now and looking for helpful suggestions.
$resultset = $connection->multi_query($sql);
pseudo:
IF $resultset > 0 (--> if the sql query returned at least one result) {
// do something
}
now the problem is with the pseudo part, i have tried to the follows:
if($resultset > 0) // takes no effect
if($resultset->num_rows > 0) // Notice: Trying to get property of non-object
I have to use multi_query so mysqli_query/mysqli_fetch_array is not a solution
thanks for the hints....
Please try:
if($connection->multi_query($sql))
{
//sample query taken from php manual, see link below
do {
/* store first result set */
if ($result = $connection->store_result()) {
while ($row = $result->fetch_row()) {
printf("%s\n", $row[0]);
}
$result->free();
}
/* print divider */
if ($connection->more_results()) {
printf("-----------------\n");
}
} while ($connection->next_result());
}
else
{
//handle error
echo mysqli_error ( $connection );
}
If you check out the documentation of multi query (here), you will see that the function returns a boolean.
Source code also taken from php manual.
multi_query() returns a boolean that indicates whether the first query was successful, it doesn't return a mysqli_result object.
You have to call the store_result() method to get the first result set.
$resultset = $connection->store_result();
To get subsequent result sets you use more_results() and next_result().
See the examples in the documentation.
Related
I got php fatal error after transfer server with php v5.6.19, before that I had no problem at all with following script
Fetch data from db table:
function get_department_list($mysqli)
{
$sql = $mysqli->query("SELECT * FROM `dept` ORDER BY `dept_id` ASC");
if($sql->num_rows > 0){
return $sql;
}else{
return false;
}
}
Populate data in HTML:
<ul class="department overflow-scroll text-center">
<?php
$shop = new Shop;
$depts = $shop->get_department_list($mysqli);
while($dept = $depts->fetch_object()){
echo '<li>'.$dept->dept_name.'</li>';
}
?>
</ul>
In the end I got an error:
Fatal error: Call to a member function fetch_object() on boolean in C:\xampp\htdocs\project\include\header.php on line 206
First, you are returning a boolean from your function. So, no wonder PHP says you so.
Second, you should keep the matters separated. a function that works with mysqli should keep all mysqli stuff inside. An return just an array, that can be used anywhere without the need to call mysqli functions again.
function get_department_list($mysqli)
{
$sql = $mysqli->query("SELECT * FROM `dept` ORDER BY `dept_id` ASC");
return $sql->fetch_all();
}
And then use not while but foreach
foreach ($depts as $dept) ...
Besides (and more for the people who may chance to land on this question looking for an answer to their question) you should always set proper error reporting for mysqli, like it shown in this answer
Update your while loop for that case when you get false from $shop->get_department_list() call
updated while like this check for $depts if any data then get $dept:
while($depts && $dept = $depts->fetch_object()){
Trying to find another simple answer but only finding complicated examples.
I'm trying to simply query a table, if there are results to display then loop through them, if there are not then display a message - unfortunately all examples I can find 'fetch' as part of the while loop, not before, so I'm trying to do:
$stm = $PdoObj->prepare("SELECT * FROM NEWS_articles");
$stm ->execute();
$results = $stm ->fetch();
if($results==null){
echo "<p>No dice, try other criteria</p>";
}else{
foreach($results as $row){
echo $row["articleName"];
}
}
The following question is close to what I'm trying to achive but was never answered satisfactorily: Is it possible to check if pdostatement::fetch() has results without iterating through a row?
You need not fetch() but fetchAll().
As mentioned by Your Common Sense use fetchAll. If there aren't any results, it will return an empty array:
$results = $stm->fetchAll();
if(empty($results))//or if(!$results) or if(count($results)==0) or if($results == array())
{
echo 'Nothing found';
}
else
{
foreach($results as $result)
{
//do stuff
}
}
The official method for getting how many rows have been returned is rowCount():
$stm->execute();
if($stm->rowCount() == 0)
{
echo 'Nothing found';
}
else
{
//do your stuff
}
Though this would not be necessary if you are already calling fetchAll as this result can be used to determine the size of the result set.
Instead of fetch() , use fetchAll().
fetchAll — Returns an array containing all of the result set rows
//Execute query and fetch first row
if ($qry=$db->query("SELECT statement")) {
if ($row=$qry->fetch_object()) {
}
}
//Same code as above using only one if statement
if ($qry=$db->query("SELECT statement") && $row=$qry->fetch_object()) {
}
Why does the second block of code (when run as a replacement to the first) produce the error "Call to function fetch_object on a non-object"?
This is because PHP isn't parsing the 2nd statement quite the way you'd expect.
It's reading it as:
if ($qry = ($db->query("SELECT statement") && $row = $qry->fetch_object()))
Which as you can see, means $qry is set before fetch_object is called on it.
Try to enclose your statements in ():
if (($qry=$db->query("SELECT statement")) && ($row=$qry->fetch_object()))
I'm using this code:
$mysqli = new mysqli(...);
$sql = file_get_contents("my_sql_file.sql");
$result = $mysqli->multi_query($sql);
if (!$result)
report_error(); //my function
while ($mysqli->more_results()) {
$result = $mysqli->next_result();
if (!$result)
report_error();
}
However the 'while' loop in the code above turned out to be an infinite loop. Anything wrong?
Actually your code doesn't really make sense. The proper way to handle multiqueries is the following (see php manual)
if ($mysqli->multi_query($query)) {
do {
// store first result set
if ($result = $mysqli->store_result()) {
while ($row = $result->fetch_row()) {
// do something with the row
}
$result->free();
}
else { error_report(); }
} while ($mysqli->next_result());
}
else { error_report(); }
The code provided in the question reaches to an infitie loop because "If your second or late query returns no result or even if your query is not a valid SQL query, more_results(); returns true in any case.", see this note on php.net: http://us3.php.net/manual/en/mysqli.multi-query.php#104076
And further more, mysqli_more_results always returns true in the code because the results are not discarded, must call mysqli_store_results to discard result after each call to mysqli_next_result. See: http://us3.php.net/manual/en/mysqli.multi-query.php#91677
There is no official way to catch all errors when executing MySQL text (multi-commands separated by semicolons) by mysqli_multi_query. The function mysqli_multi_query will stop execution when it faces a bad SQL command, so it is only possible to catch the first error (no matter where the error occurs, in the first SQL command or any other SQL command in the SQL text).
Related to Jon's answer to this question: When does mysqli_multi_query stop execution?
And as noted in http://www.php.net/manual/en/mysqli.multi-query.php#106126 The first error can be catched by scanning mysqli_next_result coz: $mysqli->next_result() will return false if it runs out of statements OR if the next statement has an error.
Finally the answer is that results must be discarded after calling to mysqli_next_result using mysqli_store_result:
$mysqli = new mysqli(...);
$sql = file_get_contents("my_sql_file.sql");
$result = $mysqli->multi_query($sql);
if (!$result)
report_error(); //my function
while ($mysqli->more_results()) {
$result = $mysqli->next_result();
//important to make mysqli_more_results false:
$discard = $mysqli->store_result();
if (!$result)
report_error();
}
I have built a class which leverages the abilities of PHP's built-in MySQLi class, and it is intended to simplify database interaction. However, using an OOP approach, I am having a difficult time with the num_rows instance variable returning the correct number of rows after a query is run. Take a look at a snapshot of my class...
class Database {
//Connect to the database, all goes well ...
//Run a basic query on the database
public function query($query) {
//Run a query on the database an make sure is executed successfully
try {
//$this->connection->query uses MySQLi's built-in query method, not this one
if ($result = $this->connection->query($query, MYSQLI_USE_RESULT)) {
return $result;
} else {
$error = debug_backtrace();
throw new Exception(/* A long error message is thrown here */);
}
} catch (Exception $e) {
$this->connection->close();
die($e->getMessage());
}
}
//More methods, nothing of interest ...
}
Here is a sample usage:
$db = new Database();
$result = $db->query("SELECT * FROM `pages`"); //Contains at least one entry
echo $result->num_rows; //Returns "0"
exit;
How come this is not accurate? Other values from result object are accurate, such as "field_count".
Possible Bug: http://www.php.net/manual/en/mysqli-result.num-rows.php#104630
Code is from source above (Johan Abildskov):
$sql = "valid select statement that yields results";
if($result = mysqli-connection->query($sql, MYSQLI_USE_RESULT))
{
echo $result->num_rows; //zero
while($row = $result->fetch_row())
{
echo $result->num_rows; //incrementing by one each time
}
echo $result->num_rows; // Finally the total count
}
Could also validate with the Procedural style:
/* determine number of rows result set */
$row_cnt = mysqli_num_rows($result);
I had the same problem and found the solution was to put:
$result->store_result();
..after the execution of the $query and before
echo $result->num_rows;
This could be normal behavior when you disable buffering of the result rows with MYSQLI_USE_RESULT
Disabling the buffer means that it`s up to you to fetch, store and COUNT the rows.
You should use the default flag
$this->connection->query($query, MYSQLI_STORE_RESULT);
Equivalent of
$this->connection->query($query)