嵌套准备好的语句和 free_result
Nested prepared statements and free_result
有人可以解释为什么 free_result
在嵌套准备语句的 while 循环后导致 bind_result
没有按预期更新值吗?
$stmt = $mysqli -> prepare("select col1 from table1 inner join ...");
$stmt -> bind_param("i", $id);
$stmt -> bind_result($col1);
$stmt -> execute() or die();
$stmt -> store_result();
$stmt2 = $mysqli -> prepare("select col2, col3 from table2 where col4 = ?");
$stmt2 -> bind_param("i", $col1);
$stmt2 -> bind_result($col2, $col3);
while ($stmt -> fetch()) {
$stmt2 -> execute() or die();
$stmt2 -> store_result();
while ($stmt2 -> fetch()) {
echo $col2 .",";
}
$stmt2 -> free_result(); // <== Works fine without this line
echo "---";
}
$stmt -> close();
$stmt2 -> close();
如果我删除 free_result
,我会得到预期的输出,比方说:
1,2,---3,4,5,---6,7,---
如果我离开它,父循环中第一个 运行 的最后结果会像这样重复:
1,2,---2,2,2,---2,2,---
我在 docs 中找不到答案...这似乎违反直觉,因为结果被保留而不是被释放。
这是一个可执行文件example
如 bind_result()
的文档所述:
All columns must be bound after mysqli_stmt_execute() and prior to calling mysqli_stmt_fetch().
如果您将 bind_result()
调用移动到适当的位置,它将起作用:
$stmt = $mysqli->prepare("select col1 from table1");
$stmt->execute();
$stmt->bind_result($col1);
$stmt->store_result();
$stmt2 = $mysqli->prepare("select col2, col3 from table2 where col4 = ?");
$stmt2->bind_param("i", $col1);
while ($stmt->fetch()) {
$stmt2->execute();
$stmt2->bind_result($col2, $col3);
$stmt2->store_result();
while ($stmt2->fetch()) {
echo $col2 .",";
}
$stmt2->free_result();
echo "---";
}
$stmt->close();
$stmt2->close();
原因是mysqli_stmt::free_result()
要求mysqlnd释放所有结果变量。引用被释放,但变量和它们的值都没有被 PHP 销毁。他们只是未绑定。
您可以停止使用 mysqli_stmt::free_result()
(您可能无论如何都应该这样做)或在每次执行后绑定结果变量。
有人可以解释为什么 free_result
在嵌套准备语句的 while 循环后导致 bind_result
没有按预期更新值吗?
$stmt = $mysqli -> prepare("select col1 from table1 inner join ...");
$stmt -> bind_param("i", $id);
$stmt -> bind_result($col1);
$stmt -> execute() or die();
$stmt -> store_result();
$stmt2 = $mysqli -> prepare("select col2, col3 from table2 where col4 = ?");
$stmt2 -> bind_param("i", $col1);
$stmt2 -> bind_result($col2, $col3);
while ($stmt -> fetch()) {
$stmt2 -> execute() or die();
$stmt2 -> store_result();
while ($stmt2 -> fetch()) {
echo $col2 .",";
}
$stmt2 -> free_result(); // <== Works fine without this line
echo "---";
}
$stmt -> close();
$stmt2 -> close();
如果我删除 free_result
,我会得到预期的输出,比方说:
1,2,---3,4,5,---6,7,---
如果我离开它,父循环中第一个 运行 的最后结果会像这样重复:
1,2,---2,2,2,---2,2,---
我在 docs 中找不到答案...这似乎违反直觉,因为结果被保留而不是被释放。
这是一个可执行文件example
如 bind_result()
的文档所述:
All columns must be bound after mysqli_stmt_execute() and prior to calling mysqli_stmt_fetch().
如果您将 bind_result()
调用移动到适当的位置,它将起作用:
$stmt = $mysqli->prepare("select col1 from table1");
$stmt->execute();
$stmt->bind_result($col1);
$stmt->store_result();
$stmt2 = $mysqli->prepare("select col2, col3 from table2 where col4 = ?");
$stmt2->bind_param("i", $col1);
while ($stmt->fetch()) {
$stmt2->execute();
$stmt2->bind_result($col2, $col3);
$stmt2->store_result();
while ($stmt2->fetch()) {
echo $col2 .",";
}
$stmt2->free_result();
echo "---";
}
$stmt->close();
$stmt2->close();
原因是mysqli_stmt::free_result()
要求mysqlnd释放所有结果变量。引用被释放,但变量和它们的值都没有被 PHP 销毁。他们只是未绑定。
您可以停止使用 mysqli_stmt::free_result()
(您可能无论如何都应该这样做)或在每次执行后绑定结果变量。