<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// 本文与 PHP 代码本身无关,仅作为演示文章输出</span></span><span>
</span><span><span class="hljs-comment">// 使用水平线分隔非正文和正文</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> <span class="hljs-string"><<<ARTICLE
----------------------------------------
# 如何将 mysqli_stmt::store_result 和 mysqli_stmt::next_result 配合使用?
在使用 PHP 的 MySQLi 扩展进行数据库操作时,如果涉及到**多结果集**(multi-result sets),就需要特别注意结果集的存储与切换。此时,`mysqli_stmt::store_result` 和 `mysqli_stmt::next_result` 两个方法往往需要配合使用,才能确保数据能够被正确读取,并且连接状态不会出错。
## 1. 背景知识
当我们在 MySQL 中执行一条可以返回多个结果集的语句(例如调用存储过程,或使用多条 `SELECT` 语句拼接),PHP 的 MySQLi 扩展会依次接收这些结果集。此时如果没有正确处理,就可能出现 **"Commands out of sync"** 的错误。
- **`mysqli_stmt::store_result`**
用于将当前结果集从 MySQL 服务器缓冲到客户端,以便后续能够安全读取和遍历数据。
- **`mysqli_stmt::next_result`**
用于移动到下一个结果集。如果有多个结果集未被处理而直接关闭连接,往往会引发错误。
## 2. 使用场景
- 调用返回多个 `SELECT` 的存储过程。
- 一次执行多条 SQL 语句时需要逐一遍历结果。
- 保证结果集被完全处理,从而避免连接状态异常。
## 3. 示例代码
```php
<?php
</span></span><span><span class="hljs-subst">$mysqli</span></span><span> = new mysqli("localhost", "user", "password", "testdb");
if (</span><span><span class="hljs-subst">$mysqli</span></span><span>->connect_errno) {
die("连接失败: " . </span><span><span class="hljs-subst">$mysqli</span></span><span>->connect_error);
}
// 假设 test_procedure 返回两个结果集
</span><span><span class="hljs-subst">$stmt</span></span><span> = </span><span><span class="hljs-subst">$mysqli</span></span><span>->prepare("CALL test_procedure()");
</span><span><span class="hljs-subst">$stmt</span></span><span>->execute();
// 循环处理多个结果集
do {
// 将当前结果集缓冲到客户端
if (</span><span><span class="hljs-subst">$stmt</span></span><span>->store_result()) {
while (</span><span><span class="hljs-subst">$row</span></span><span> = </span><span><span class="hljs-subst">$stmt</span></span><span>->fetch()) {
// 在这里处理数据
var_dump(</span><span><span class="hljs-subst">$row</span></span><span>);
}
}
// 移动到下一个结果集
} while (</span><span><span class="hljs-subst">$stmt</span></span><span>->next_result());
</span><span><span class="hljs-subst">$stmt</span></span><span>->close();
</span><span><span class="hljs-subst">$mysqli</span></span><span>->close();
</span></span>
結果セットを処理する必要がない場合でも、それを呼び出して、データが正しくリリースされていることを確認してください。
next_resultと協力します
結果セットの読み取りを完了した後、次のセットを入力するためにnext_resultを呼び出す必要があります。そうしないと、後続の操作がブロックされます。
エラー処理<br> 複雑なストアドプロシージャでは、エラーチェックをループに追加して、結果セットに問題がある場合に時間内に中止できるようにすることをお勧めします。
MySQLのマルチリエルティセットを使用する場合、 mysqli_stmt :: store_resultおよびmysqli_stmt :: next_resultは重要なツールのペアです。前者は結果セットを安全にキャッシュする責任があり、後者は次の結果セットに反復する責任があります。両方を使用すると、Multi-result SetシナリオがPHPアプリケーションで安定して正しく処理され、一般的な接続エラーを回避できます。
記事;
<span></span>
関連タグ:
mysqli_stmt