如何从预准备语句中获取 assoc 数组中的所有内容


How to fetch all in assoc array from a prepared statement?

我正在尝试以下代码:

    if ($result = $this->mysqli->prepare("SELECT * FROM `mytable` WHERE `rows1`=?"))
    {
        $result->bind_param("i",$id);
        $result->execute();
        while ($data = $result->fetch_assoc())
        {
            $statistic[] = $data;
        }
        echo "<pre>";
        var_dump($statistic);
        echo "</pre>";
    }

但它抛出以下错误

[2012 年 6 月 15 日星期五 12:13:11] [错误] [客户端 127.0.0.1] PHP 致命错误: 调用 [myfile.php] 中的未定义方法 mysqli_stmt::fetch_assoc()

我也试过:

if ($result = $this->mysqli->prepare("SELECT * FROM `mytable` WHERE `rows1`=?"))
    {
        $result->bind_param("i",$id);
        $rows = $result->execute();
        while ($data = $rows->fetch_assoc())
        {
            $statistic[] = $data;
        }
        echo "<pre>";
        var_dump($statistic);
        echo "</pre>";
    }

这使得:

[2012 年 6 月 15 日星期五 12:22:59] [错误] [客户端 127.0.0.1] PHP 致命错误: 调用非对象上的成员函数 fetch_assoc() [我的文件.php]

还能做些什么来获得结果或我做错了什么?我需要来自数据库的assoc数组看起来像$data[0]["id"] = 1

事实上你可以很容易地做到这一点,只是你不能用mysqli_stmt对象做到这一点,你必须提取底层mysqli_result,你可以通过简单地调用mysqli_stmt::get_result()来做到这一点。注意:这需要mysqlnd(MySQL本机驱动程序)扩展,而该扩展可能并不总是可用。

然而,下面关于推荐PDO而不是MySQLi的观点仍然存在,这是一个典型的例子:MySQLi用户空间API毫无意义。我花了几年时间间歇性地使用 MySQLi 才发现上面概述的机制。现在,我承认将语句和结果集概念分开确实有意义,但在这种情况下,为什么语句具有fetch()方法?值得深思(如果你仍然坐在MySQLi和PDO之间的栅栏上)。

为了完整起见,下面是一个基于(松散地)问题中原始代码的代码示例:

// Create a statement
$query = "
    SELECT *
    FROM `mytable`
    WHERE `rows1` = ?
";
$stmt = $this->mysqli->prepare($query);
// Bind params and execute
$stmt->bind_param("i", $id);
// Extract result set and loop rows
$result = $stmt->get_result();
while ($data = $result->fetch_assoc())
{
    $statistic[] = $data;
}
// Proof that it's working
echo "<pre>";
var_dump($statistic);
echo "</pre>";

你可以做:

$stmt = $this->mysqli->prepare("SELECT * FROM `mytable` WHERE `rows1`=?");
$stmt->bind_param("i",$id);
$stmt->execute();
$result = $stmt->get_result();
$statistic = $result->fetch_all(MYSQLI_ASSOC);

$statistic包含二维数组中的所有结果。

*需要注意的是,此mysqli_fetch_all()功能仅适用于mysqlnd包。http://php.net/manual/en/mysqli-result.fetch-all.php

我不喜欢 Mysqli,但你可以在 ready 时这样做。

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$db = new mysqli('hostAddress', 'username', 'password', 'databaseName');
$db->set_charset('utf8mb4');
$userID = 2;
$stmt = $db->prepare("SELECT * FROM users WHERE ID = ?");
$stmt->bind_param("i", $userID);
// because the variable is bound by reference you can assign the value after binding, too
//$userID = 2;
$stmt->execute();

如果你想要结果;

$result = $stmt->get_result();
$user   = $result->fetch_array(MYSQLI_ASSOC); //one row

或多行

$users  = $result->fetch_all(MYSQLI_ASSOC);

使用预准备语句,您不需要数组,但可以自由使用它。使用bind_result mysqli_stmt方法,您不会遇到任何麻烦。在bind_result中,您定义了变量,其中列值的存储顺序应与从数据库请求列值的顺序相同。您可以使用本机变量或数组键来执行此操作。请参阅 PHP 文档 mysqli_stmt::bind_result

你问你的代码有什么问题,这是滥用$result->执行。$result->execute() 返回一个布尔值,而不是您期望的实例mysqli_result。请参阅 PHP 文档 mysqli_stmt::执行

假设您的数据库表"mytable"具有以下列:id (int)、field1 (varchar)、field2(date)

然后代码将如下所示:

// Initialize the array with some default values if you really want to use an array
$data = array('id'=>0,'field1'=>'','field2'=>'');
/* I recommend to explicitly define which columns you want to retrieve so you don't have to rely that the columns in the database are set in the desired order and on otherhand it doesn't matter if the database table has more columns that you want to retrieve, the code will still work as long as the columns with this names exist.*/
if ($result = $this->mysqli->prepare("SELECT `id`,`field1`,`field2` FROM `mytable` WHERE `rows1`=?"))
    {
        $result->bind_param("i",$id);
        $result->bind_result("iss", $data['id'], $data['field1'], $data['field2']);
        $result->execute();
        while($result->fetch())
        {
            $statistic[] = $data;
        }
        echo "<pre>";
        var_dump($statistic);
        echo "</pre>";
    }