PHP我何时以及为什么需要调用store_result()?

时间:2016-05-12 11:25:50

标签: php mysqli

在我找到的PHP manual

  

您必须为每个查询调用 mysqli_stmt_store_result()   成功生成结果集(SELECT,SHOW,DESCRIBE,EXPLAIN),   当且仅当您想缓冲完整的结果集时   客户端,以便后续的mysqli_stmt_fetch()调用返回   缓冲数据。

我根本不明白这个解释。特别是,我不知道缓冲区对客户端设置完整结果的意义。

例如,如果我想获得select查询的num_rows数量,我通常会这样做:

$result = $mysqli->query("SELECT name FROM users WHERE age ='3' "));
echo $result->num_rows;

如果我现在使用准备好的陈述,那么

$sql = 'SELECT name FROM users WHERE age = ?';
$stmt->prepare($sql);
$stmt->bind_param('i', 3);
$stmt->execute();
// $stmt->store_result();
$numrows = $stmt->num_rows;

总是返回0,除非我取消注释// $stmt->store_result();。我虽然准备+ bind + execute应该与旧的query命令相同,但显然不是。 store_result方法在做什么?我为什么需要它?

1 个答案:

答案 0 :(得分:2)

必须调用store_result()的原因是,默认情况下,mysqli中的预处理语句在无缓冲模式下运行。

这与the docs中提供的信息相反。您必须记住,mysqli是作为填充程序而不是适当的数据库库开发的。 MySQLi充满了错误,并且遭受许多错误的决定。其中之一是预处理语句的非缓冲模式。

实际上,您根本不需要使用store_result()。此功能不是很有用,因为您仍然需要将结果绑定到变量并分别获取每一行。更好的选择是get_result()

$age = 3;
$sql = 'SELECT name FROM users WHERE age = ?';
$stmt->prepare($sql);
$stmt->bind_param('i', $age);
$stmt->execute();
$result = $stmt->get_result();

query()方法相比,这是4行,但是最终结果是相同的。 $result包含mysqli_result类的实例。

您可以为此编写自己的包装器,以简化生活。这是一个示例,说明如何使用包装函数将其变成一行。

function mysqli_prepared_query(mysqli $mysqli, string $sql, array $params): mysqli_result
{
    $stmt = $mysqli->prepare($sql);
    $stmt->bind_param(str_repeat("s", count($params)), ...$params);
    $stmt->execute();
    return $stmt->get_result();
}

$result =  mysqli_prepared_query($mysqli, 'SELECT ?,?', [1, 2]);

当然,最好的解决方案是切换到PDO或使用某种抽象库,这样您就不必处理这些令人困惑的方法。