如何从准备好的语句中获取数据

准备好的陈述

请参阅 MySQLi 中的 Prepared 语句, 了解如何准备和执行查询。

结果的约束力

面向对象的风格

$stmt->bind_result($forename);

程序风格

mysqli_stmt_bind_result($stmt, $forename);

使用 bind_result 的问题是它需要语句来指定将使用的列。这意味着对于上面的工作,查询必须看起来像这个 SELECT forename FROM users。要包含更多列,只需将它们作为参数添加到 bind_result 函数中(并确保将它们添加到 SQL 查询中)。

在这两种情况下,我们都将 forename 列分配给 $forename 变量。这些函数使用与要分配的列一样多的参数。赋值只进行一次,因为函数通过引用绑定。

然后我们可以循环如下:

面向对象的风格

while ($stmt->fetch())
    echo "$forename<br />";

程序风格

while (mysqli_stmt_fetch($stmt))
    echo "$forename<br />";

这样做的缺点是你必须一次分配很多变量。这使得难以跟踪大型查询。如果你安装了 MySQL Native Driver(mysqlnd ,你需要做的就是使用 get_result

面向对象的风格

$result = $stmt->get_result();

程序风格

$result = mysqli_stmt_get_result($stmt);

容易使用,因为现在我们得到一个 mysqli_result 对象。这与 mysqli_query 返回的对象相同。这意味着你可以使用常规结果循环来获取数据。

如果我不能安装 mysqlnd 怎么办?

如果是这样的话那么 @Sophivorus 会让你满意这个惊人的答案

此功能可以执行 get_result 的任务,而无需在服务器上安装。它只是遍历结果并构建一个关联数组

function get_result(\mysqli_stmt $statement)
{
    $result = array();
    $statement->store_result();
    for ($i = 0; $i < $statement->num_rows; $i++)
    {
        $metadata = $statement->result_metadata();
        $params = array();
        while ($field = $metadata->fetch_field())
        {
            $params[] = &$result[$i][$field->name];
        }
        call_user_func_array(array($statement, 'bind_result'), $params);
        $statement->fetch();
    }
    return $result;
}

然后我们可以使用该函数来获得这样的结果,就像我们使用 mysqli_fetch_assoc() 一样

<?php
$query = $mysqli->prepare("SELECT * FROM users WHERE forename LIKE ?");
$condition = "J%";
$query->bind_param("s", $condition);
$query->execute();
$result = get_result($query);

while ($row = array_shift($result)) {
    echo $row["id"] . ' - ' . $row["forename"] . ' ' . $row["surname"] . '<br>';
}

它将具有与使用 mysqlnd 驱动程序相同的输出,但不必安装。如果你无法在系统上安装所述驱动程序,这非常有用。只需实施此解决方案。