PHP中使用Mysqli:如何访问存储结果并执行多查询
问题说明
你有一段已绑定参数的MySQLi SELECT语句,执行后返回单行数据:
$statement = $mysqli->prepare($sql); $statement->bind_param('s', $id); $statement->execute();
需要释放MySQLi资源以执行第二个SELECT查询,但遇到以下问题:
- 使用
$statement->store_result()后,$statement->fetch()仅返回布尔值true,无法获取实际数据 - 使用
get_result()获取结果后,执行第二个查询时抛出错误:"Commands out of sync; you can't run this command now" - 尝试先获取结果再调用
store_result(),仍出现相同错误
你需要实现:既能执行新查询,又能保留对第一个查询结果的访问权限,且已知必须通过$statement->free_result()避免错误。
解决方案
核心逻辑是:读取完第一个查询的结果后,立即释放对应语句的资源,同时将结果保存到普通变量中,后续直接使用该变量即可,无需依赖原语句或结果集对象,这样MySQLi连接就能被新查询安全复用。
针对你提供的代码,修改后的完整示例
function display_video($id,$order='ASC') { $mysqli = new mysqli(getenv('O_HOST'), getenv('O_USER'), getenv('O_PW'), getenv('O_DB')); if ($mysqli->connect_errno) { die("无法连接数据库: " . $mysqli->connect_error); } mysqli_set_charset($mysqli,"utf8"); $sql = "SELECT `data` FROM `videos` WHERE `VidID` LIKE ? ORDER BY `Pub_date` $order"; $statement = $mysqli->prepare($sql); $statement->bind_param('s', $id); $statement->execute(); $result = $statement->get_result(); // 将查询结果读取到变量,后续直接使用这个变量访问数据 $row = $result->fetch_assoc(); // 关键:读完结果后立即释放语句资源,再关闭结果集 $statement->free_result(); $result->close(); if (empty($row)) { echo "<p>未找到视频 $id。</p>" . PHP_EOL; $mysqli->close(); return false; } // <<<< 生成HTML代码 >>>> get_relations($row["VidID"],$row["lang"],$row['RelatedID'],$row['MediaID'],$mysqli,$related); // <<<< 使用$related生成更多HTML代码 >>>> $mysqli->close(); } function get_relations($id,$lang,$relID,$mID,$db,&$rel_list){ do{ $sql="SELECT `data` FROM `videos` WHERE `vidID` LIKE ?"; $statement=$db->prepare($sql); $statement->bind_param('i',$relID); $statement->execute(); $result = $statement->get_result(); if ($result->num_rows > 0) { $row = $result->fetch_assoc(); // 读完当前结果后立即释放语句资源 $statement->free_result(); $result->close(); // <<<< 处理数据 >>>> }else{ // 即使无结果也要释放资源 $statement->free_result(); $result->close(); return false; } }while($relID!=$id); return true; }
关键注意事项
- 必须释放语句资源:每个
prepared statement在读取完结果后,都要调用$statement->free_result(),这是解决"Commands out of sync"错误的核心,它会释放语句占用的MySQLi连接资源,让连接可以被新查询使用。 - 结果保存到变量:第一个查询的结果已经被读取到
$row变量中,后续无需再依赖原$statement或$result对象,直接通过$row访问数据即可。 - 使用
store_result()的替代方案:如果要使用store_result()而不是get_result(),需要结合bind_result()绑定字段变量,示例如下:
$statement = $mysqli->prepare($sql); $statement->bind_param('s', $id); $statement->execute(); // 绑定查询结果的字段到对应变量 $statement->bind_result($data); // 将结果存储到内部缓冲区 $statement->store_result(); // 填充绑定的变量 $statement->fetch(); // 释放语句资源 $statement->free_result(); // 后续直接使用$data变量访问查询到的数据
内容的提问来源于stack exchange,提问作者rayvd
相关产品推荐
相关产品推荐

