【问题标题】:Why does mysqli_result::free_result not work on mysqli_stmt::get_result为什么 mysqli_result::free_result 在 mysqli_stmt::get_result 上不起作用
【发布时间】:2022-01-25 12:07:59
【问题描述】:

我有以下代码:

$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;  

我知道我可以简单地使用 $stmt->free_result,但是 php 文档 https://www.php.net/manual/en/mysqli-result.free.php 提到您也可以在 mysqli_result 对象上使用 free_result,所以我们为什么不能在 mysqli_stmt->get_result() 上使用它,这是一个结果对象也是?

【问题讨论】:

  • 也可以查看stackoverflow.com/questions/14554517/…等其他问题
  • @Progman 你的链接没有解释get_result
  • 您使用了两次$stmt->get_result()。你为什么这样做?
  • @Progman 因为第一次使用我需要得到num_rows,第二次我想使用free_result,这样我就可以在$stmt 中使用我的第二个查询。文档没有提到 get_result 刷新结果,这是我认为正在发生的事情,因为不使用 free_result 允许我运行第二个查询

标签: php mysqli


【解决方案1】:

mysqli_stmt::get_result() 不是幂等的。您只能调用一次。如果再次调用它会报错:

命令不同步;你现在不能运行这个命令

此错误与 free_result() 无关,您可能不应该以您显示的方式使用它。

您需要将结果存储在一个变量中,然后才能执行您想要的所有操作。

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

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

我还建议您永远不要使用free_result()

说明
当 mysqli 调用 MySQL 服务器以执行准备好的语句时,服务器将生成一个结果集。这不是EXECUTE 调用的结果,而是SQL 的实际输出。默认情况下,mysqli prepared statementsunbuffered mode 中运行,这意味着 PHP 在执行时不会从服务器获取结果。您必须使用其中一个函数从 MySQL 服务器中检索它。您可以使用fetch() 逐行执行此操作,您可以使用store_result() 告诉PHP 将结果集缓冲到内部内存中,或者您可以使用get_result() 让PHP 缓冲封装在mysqli_result 对象中的结果。只要 MySQL 服务器上有待处理的行,连接线就会处于忙碌状态。

一旦您从 MySQL 获取结果,就没有其他可读取的内容了。如果您尝试再次阅读,您将收到上述 OOS 错误。这就是为什么你不能多次调用get_result() 并期望得到相同的结果。一旦数据被提取到 PHP 中,它就会从线路中消失,现在存储在 PHP 内存中。准备好的语句当然可以再次执行,并产生一个新的结果集。

另见mysqli - Executing statements

【讨论】:

  • #1 mysqli_stmt::get_result() 不是幂等的 - 你可以添加一些参考(php 文档?)来备份它。 #2 get_result() 是否也像 free_reult() 一样清除缓冲区?如果是,那么我可以使用多个$stmt->execute; $stmt->get_result() 查询,甚至不用担心清除结果缓冲区吗?
  • @user31782 恐怕mysqli不适合你。它的 API 令人困惑且低级。您确实应该了解客户端-服务器交互以完全了解 mysqli。对于大多数用途,PDO 会更好。我试图解释为什么get_result() 不是幂等的,我希望这可以澄清事情。
  • FWIW 我认为你应该完全忘记free_result() 的存在。这是一个没有太多用处的奇怪函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多