PHP Conference Japan 2024

mysqli_stmt::store_result

mysqli_stmt_store_result

(PHP 5, PHP 7, PHP 8)

mysqli_stmt::store_result -- mysqli_stmt_store_result将结果集存储在内部缓冲区中

描述

面向对象风格

public mysqli_stmt::store_result(): bool

过程化风格

mysqli_stmt_store_result(mysqli_stmt $statement): bool

此函数应仅在需要将完整结果集缓冲到 PHP 中时,用于成功生成结果集的查询(例如 SELECT, SHOW, DESCRIBE, EXPLAIN)。每个后续的 mysqli_stmt_fetch() 调用将返回缓冲数据。

注意:

对于其他查询,无需调用 mysqli_stmt_store_result(),但如果调用,则在所有情况下都不会造成任何损害或导致任何明显的性能损失。可以通过检查 mysqli_stmt_result_metadata() 是否返回 false 来检测查询是否生成了结果集。

参数

statement

仅过程化风格:由 mysqli_stmt_init() 返回的 mysqli_stmt 对象。

返回值

成功时返回 true,失败时返回 false

错误/异常

如果启用了 mysqli 错误报告 (MYSQLI_REPORT_ERROR) 并且请求的操作失败,则会生成警告。此外,如果模式设置为 MYSQLI_REPORT_STRICT,则会抛出 mysqli_sql_exception

示例

示例 #1 面向对象风格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

$query = "SELECT Name, CountryCode FROM City ORDER BY Name LIMIT 20";
$stmt = $mysqli->prepare($query);
$stmt->execute();

/* 将结果存储在内部缓冲区中 */
$stmt->store_result();

printf("Number of rows: %d.\n", $stmt->num_rows);

示例 #2 过程化风格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

$query = "SELECT Name, CountryCode FROM City ORDER BY Name LIMIT 20";
$stmt = mysqli_prepare($link, $query);
mysqli_stmt_execute($stmt);

/* 将结果存储在内部缓冲区中 */
mysqli_stmt_store_result($stmt);

printf("Number of rows: %d.\n", mysqli_stmt_num_rows($stmt));

以上示例将输出

Number of rows: 20.

参见

添加注释

用户贡献的注释 5 条注释

kitlum AT ukr DOT net
9 年前
花费了一些时间才找到如何将 mysqli_stmt 的多行结果保存到数组中,当 get_result 被禁止时。
可行的方案是使用 store_result
$stmt=$this->mysqli->prepare("SELECT surname, name, user_id, last_m_own, last_m_str, role FROM users WHERE referer_id=(?)");
$stmt->bind_param('i',$referer_id);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($ans['surname'], $ans['name'], $ans['user_id'], $ans['last_m_own'], $ans['last_m_str'], $ans['role']);
$j=$stmt->num_rows;
for ($i=0;$i<$j;$i++){
$stmt->data_seek($i);
$stmt->fetch();
foreach ($ans as $key=>$value){
$result[$i][$key]=$value;
}
}
希望对像我这样的新手有所帮助
pcc at pccglobal dot com
14 年前
当使用 prepare 准备一个检索 LOB 的语句时,方法的顺序很重要。
此外,必须调用方法 'store_result()',并且必须按正确的顺序调用。
不遵守此规则会导致 PHP/MySQLi 崩溃或返回错误的值。
正确的方法顺序是:prepare -> execute -> store_result -> bind -> fetch
以下适用于运行 IIS/6.0 + PHP 5.2.1 的 Windows SBS 服务器
MySQL 服务器版本 5.0.26-community-nt,客户端版本 5.0.51a

<?php
$database
= "test" ;
$table = "test" ;
$column = "flongblob" ;
$mysqli = new mysqli("localhost", "root", "<secret_password>", $database);
// 正确的流程顺序:prepare -> execute -> store_result -> bind -> fetch
$stmt = $mysqli->prepare("SELECT `$column` FROM `$table`") ;
$stmt->execute();
$stmt->store_result();
// 获取一条记录。将结果绑定到名为'value'的变量并获取。
$stmt->bind_result($value) ;
$res = $stmt->fetch() ;
if(
$res)
{
// strlen($value) 应该包含 LOB 的长度,而不是 1 或 0。
echo "$column 数据长度为 " . strlen($value) . " 字节。\n" ;
}
else
{
echo ((
false !== $res) ? "数据结束" : $stmt->error) . "\n" ;
break ;
}
// 获取另一条记录。
$res = $stmt->fetch() ;
if(
$res)
{
// strlen($value) 应该包含 LOB 的长度,而不是 1 或 0。
echo "$column 数据长度为 " . strlen($value) . " 字节。\n" ;
}
else
{
echo ((
false !== $res) ? "数据结束" : $stmt->error) . "\n" ;
break ;
}
$stmt->close() ;
$mysqli->close() ;
exit ;
?>

以上示例应该输出
flongblob 数据长度为 932353 字节。
flongblob 数据长度为 867300 字节。

如果流程顺序错误,MySQLi 会崩溃或输出
flongblob 数据长度为 0 字节。
flongblob 数据长度为 867300 字节。
neromir at hotmail dot com
16 年前
上面在函数初始描述中的措辞可能会令人困惑(如下所示)。

"对于每个成功生成结果集(SELECT、SHOW、DESCRIBE、EXPLAIN)的查询,您都必须调用 mysqli_stmt_store_result(),并且只有当您希望客户端缓冲整个结果集时才需要调用,以便后续的 mysqli_stmt_fetch() 调用返回缓冲数据。"

我最初将“并且只有当您希望...”部分理解为只有在想要缓冲结果集时才需要调用此函数。但是,情况并非如此,这种误解给我带来了不少麻烦。

因此,为了澄清任何遇到相同误解的人,据我所知,您**始终**必须为每个生成结果集的查询(如引号中括号内列出的)调用此函数。
UCFirefly (at) yahoo.com
18 年前
fetch_fields() 似乎与这里使用的预处理语句不兼容。如果您使用通配符,则会使事情变得困难。我猜想这在某种模糊的方式下对安全性更好。
Typer85 at gmail dot com
17 年前
针对我下方关于 mysqli_fetch_fields 与预处理语句不兼容的说法进行回复。

这是错误的,它可以兼容,但您需要做一些额外的工作。我建议您使用某种包装函数来处理这些繁琐的事情,但基本思想是相同的。

假设您有一个如下所示的预处理语句。为了简单起见,我将使用过程式方法,但相同的想法也可以使用面向对象的方式完成

<?php

// 连接 Blah Blah Blah。

$connectionLink = mysqli_connect( .... );

// 查询 Blab Blah Blah。

$query = "Select `Id` From `Table` Where `Id` = ?";

// 准备查询。

$prepareObject = mysqli_prepare( $connectionLink , $query );

// 绑定查询。

mysqli_stmt_bind_param( $prepareObject , 'i' , 1 );

// 执行查询。

mysqli_stmt_execute( $prepareObject );

?>

现在,以上所有内容对于熟悉使用预处理语句的任何人来说都是很好理解的,但如果我想使用 mysqli_fetch_fields 或任何其他获取有关结果集元信息的函数,但这些函数不适用于预处理语句呢?

使用特殊的函数 mysqli_stmt_result_metadata。它可以按如下方式使用,假设以下代码段紧接在上述代码段之后。

<?php

$metaData
= mysqli_stmt_result_metadata( $prepareObject );

// 我现在可以使用变量
// $metaData 作为参数调用 mysqli_fetch_fields。

$fieldInfo = mysqli_fetch_fields( $metaData );

// 或者这样。

$fieldInfo = mysqli_num_fields( $metaData );

?>

请查看 mysqli_stmt_result_metatdata 函数的手册条目,了解有关如何使用预处理语句公开它的完整详细信息。

祝你好运,
To Top