简体   繁体   中英

Why does mysqli_result::free_result not work on mysqli_stmt::get_result

I have the following code:

$post_title = "Some dynamic POST data";
$stmt = $conn->prepare("SELECT * FROM `posts` WHERE title=? ");
$stmt->bind_param("s", $post_title);
$stmt->execute();
$rows = $stmt->get_result()->num_rows;  
$stmt->get_result()->free_result(); // throws error: commands out of sync 


$stmt = $conn->prepare("... some new condition");
$stmt->bind_param(...);
$stmt->execute();
$rows = $stmt->get_result()->num_rows;  

I know I can simply use $stmt->free_result , but the php docs https://www.php.net/manual/en/mysqli-result.free.php mention you can use free_result on mysqli_result object as well so why can't we use it on mysqli_stmt->get_result() , which is a result object as well?

They're different methods.

It is either ->free(); on the result, or ->free_result(); on the statement.

mysqli_stmt::get_result() is not idempotent. You can only call it once. If you call it again you will get an error:

Commands out of sync; you can't run this command now

This error has nothing to do with free_result() which you probably should not be using in the way you showed anyway.

You need to store the result in a variable and only then you can perform all the operations you want.

$stmt = $mysqli->prepare("SELECT ? ");
$stmt->bind_param("s", $post_title);
$stmt->execute();

$result = $stmt->get_result();
$rows = $result->num_rows;  
$result->free_result();

I would also recommend that you don't ever use free_result() .

Explanation :
When mysqli makes a call to MySQL server to execute a prepared statement, the server will produce a result set. This is not the outcome of the EXECUTE call, but the actual output of the SQL. By default, mysqli prepared statements are running in unbuffered mode , which means that upon execution PHP will not fetch the results from the server. You must use one of the functions to retrieve it from the MySQL server. You can do it row by row using fetch() , you can tell PHP to buffer the result set in internal memory using store_result() or you can ask PHP to buffer the result encapsulated in a mysqli_result object using get_result() . The connection line will be busy as long as there are pending rows on the MySQL server.

Once you fetch the results from MySQL, there is nothing else to read. If you try to read again, you will get OOS error mentioned above. This is why you can't call get_result() multiple times and expect the same result. Once the data is fetched to PHP, it's gone from the line, and is now stored in PHP memory. The prepared statement can of course be executed again and a new result set will be produced.

See also mysqli - Executing statements .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM