PHP Conference Japan 2024

mysqli_stmt::fetch

mysqli_stmt_fetch

(PHP 5, PHP 7, PHP 8)

mysqli_stmt::fetch -- mysqli_stmt_fetch将预处理语句的结果提取到绑定的变量中

描述

面向对象风格

public mysqli_stmt::fetch(): ?bool

过程化风格

mysqli_stmt_fetch(mysqli_stmt $statement): ?bool

将预处理语句的结果提取到由 mysqli_stmt_bind_result() 绑定的变量中。

注意:

请注意,在调用 mysqli_stmt_fetch() 之前,必须由应用程序绑定所有列。

注意:

数据在不调用 mysqli_stmt_store_result() 的情况下进行无缓冲传输,这可以提高性能(但会降低内存成本)。

参数

statement

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

返回值

返回值
描述
true 成功。数据已提取
false 发生错误
null 没有更多行/数据存在或数据截断发生

错误/异常

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

示例

示例 #1 面向对象风格

<?php
$mysqli
= new mysqli("localhost", "my_user", "my_password", "world");

/* 检查连接 */
if (mysqli_connect_errno()) {
printf("连接失败:%s\n", mysqli_connect_error());
exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 150,5";

if (
$stmt = $mysqli->prepare($query)) {

/* 执行语句 */
$stmt->execute();

/* 绑定结果变量 */
$stmt->bind_result($name, $code);

/* 提取值 */
while ($stmt->fetch()) {
printf ("%s (%s)\n", $name, $code);
}

/* 关闭语句 */
$stmt->close();
}

/* 关闭连接 */
$mysqli->close();
?>

示例 #2 过程化风格

<?php
$link
= mysqli_connect("localhost", "my_user", "my_password", "world");

/* 检查连接 */
if (mysqli_connect_errno()) {
printf("连接失败:%s\n", mysqli_connect_error());
exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 150,5";

if (
$stmt = mysqli_prepare($link, $query)) {

/* 执行语句 */
mysqli_stmt_execute($stmt);

/* 绑定结果变量 */
mysqli_stmt_bind_result($stmt, $name, $code);

/* 提取值 */
while (mysqli_stmt_fetch($stmt)) {
printf ("%s (%s)\n", $name, $code);
}

/* 关闭语句 */
mysqli_stmt_close($stmt);
}

/* 关闭连接 */
mysqli_close($link);
?>

以上示例将输出

Rockford (USA)
Tallahassee (USA)
Salinas (USA)
Santa Clarita (USA)
Springfield (USA)

参见

添加注释

用户贡献的注释 5 条注释

19
Bruce Martin
12 年前
我试图使用一个通用的 select * from table 语句,并将结果返回到数组中。我最终想出了这个解决方案,其他人也有类似的解决方案,但它们对我来说不起作用。
<?php
//片段:使用常规方法到达此点
$stmt->execute();
$metaResults = $stmt->result_metadata();
$fields = $metaResults->fetch_fields();
$statementParams='';
//动态构建 bind_results 语句,以便将结果获取到数组中
foreach($fields as $field){
if(empty(
$statementParams)){
$statementParams.="\$column['".$field->name."']";
}else{
$statementParams.=", \$column['".$field->name."']";
}
}
$statment="\$stmt->bind_result($statementParams);";
eval(
$statment);
while(
$stmt->fetch()){
//现在数据包含在关联数组 $column 中。如果您需要执行 foreach 或
//如果您很懒,并且不想为每个参数编写绑定代码,这将非常有用。
}
// 继续执行后续操作。
?>
6
dan dot latter at gmail dot com
17 年前
以下函数取自 PHP Cookbook 2,返回结果集中一行数据的关联数组,放在 while 循环中以迭代整个结果集。

<?php
public function fetchArray () {
$data = mysqli_stmt_result_metadata($this->stmt);
$fields = array();
$out = array();

$fields[0] = &$this->stmt;
$count = 1;

while(
$field = mysqli_fetch_field($data)) {
$fields[$count] = &$out[$field->name];
$count++;
}

call_user_func_array(mysqli_stmt_bind_result, $fields);
mysqli_stmt_fetch($this->stmt);
return (
count($out) == 0) ? false : $out;

}
?>
1
piedone at pyrocenter dot hu
16 年前
我尝试了提到的 stmt_bind_assoc() 函数,但不知何故,非常奇怪的是它不允许将值写入数组!在 while 循环中,行被正确获取,但如果我写 $array[] = $row;,数组将填充数据集的最后一个元素... 不幸的是,我找不到解决方案。
3
Lyndon
16 年前
此函数使用与上一个函数相同的思路,但它将字段绑定到给定的数组。
<?php
function stmt_bind_assoc (&$stmt, &$out) {
$data = mysqli_stmt_result_metadata($stmt);
$fields = array();
$out = array();

$fields[0] = $stmt;
$count = 1;

while(
$field = mysqli_fetch_field($data)) {
$fields[$count] = &$out[$field->name];
$count++;
}
call_user_func_array(mysqli_stmt_bind_result, $fields);
}

// 示例

$stmt = $mysqli->prepare("SELECT name, userid FROM somewhere");
$stmt->execute();

$row = array();
stmt_bind_assoc($stmt, $row);

// 循环遍历所有结果行
while ($stmt->fetch()) {
print_r($row);
}
?>
2
andrey at php dot net
19 年前
重要提示:在使用此函数处理大型结果集或 BLOB/TEXT 列时要小心。当一个或多个列的类型为 (MEDIUM|LONG)(BLOB|TEXT) 并且未调用 ::store_result() 时,mysqli_stmt_fetch() 将尝试为每个此类列分配至少 16MB 的内存。这_无关紧要_结果集中最长值例如只有 30 字节,将分配 16MB。因此,在获取大量数据时,最好不要使用参数绑定。为什么?因为数据首先存储在 MySQL 结果集中(内存中),然后第二次存储在 PHP 变量中。
To Top