如何在同一PHP页面多次使用mysqli fetch_assoc()处理预准备语句?
解决PHP预准备语句结果集多次调用fetch_assoc()的问题
哈哈,这个坑我刚踩过不久!问题出在fetch_assoc()的工作机制上——它会顺着结果集的内部指针逐行读取,读完一遍之后指针就停在结果集的末尾了,再调用自然就返回null了。给你两个实用的解决办法,看你需求选:
方案1:把结果集提前转成数组(推荐小数据集)
直接把所有查询结果一次性读取到一个数组里,之后想循环多少次、取多少次都随便来,完全不用管指针的事。用fetch_all(MYSQLI_ASSOC)就能实现:
$data = $conn->prepare("SELECT * FROM some_table WHERE id=?"); $data->bind_param('i',$id); $data->execute(); $result = $data->get_result(); // 一次性把所有行存入数组,键是字段名 $all_records = $result->fetch_all(MYSQLI_ASSOC); // 第一次循环遍历所有数据 foreach ($all_records as $record) { echo $record['first_name'] . "<br>"; } // 单次获取第一行数据 if (!empty($all_records)) { $first_user = $all_records[0]; $first_name = $first_user['first_name']; } // 甚至可以再来第二次循环 foreach ($all_records as $record) { // 做其他处理逻辑 }
这个方法的好处是直观,操作起来灵活,缺点是如果结果集特别大(比如几万行),会占用较多内存。
方案2:重置结果集指针(适合大数据集)
如果不想把所有数据都存进内存,可以用data_seek(0)把结果集的内部指针重置到开头位置,这样就能再次调用fetch_assoc()了:
$data = $conn->prepare("SELECT * FROM some_table WHERE id=?"); $data->bind_param('i',$id); $data->execute(); $result = $data->get_result(); // 第一次循环读取所有数据 while ($row = $result->fetch_assoc()) { echo $row['first_name'] . "<br>"; } // 重置指针到结果集的第一行(索引从0开始) $result->data_seek(0); // 现在可以单次获取第一行数据 $user = $result->fetch_assoc(); $first_name = $user['first_name']; // 还能再次循环读取 $result->data_seek(0); while ($row = $result->fetch_assoc()) { // 执行另一套处理逻辑 }
注意:这个方法只对缓冲结果集有效,而你用get_result()得到的结果集正好是缓冲的,所以完全没问题。如果是无缓冲结果集(比如用store_result()搭配bind_result()的情况),data_seek()可能无法使用。
内容的提问来源于stack exchange,提问作者Grogu
相关产品推荐
相关产品推荐

