嵌套准备好的语句和 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()(您可能无论如何都应该这样做)或在每次执行后绑定结果变量。