2024 年 PHP 日本研討會

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("列數:%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 年前
花了好幾個小時才找出如何在 get_result 被禁止的情況下,將 mysqli_stmt 的多行結果儲存到陣列中。
可行的想法是使用 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 或零。
echo "$column 資料長度為 " . strlen($value) . " 位元組。\n" ;
}
else
{
echo ((
false !== $res) ? "資料結束" : $stmt->error) . "\n" ;
break ;
}
// 提取另一條記錄。
$res = $stmt->fetch() ;
if(
$res)
{
// strlen($value) 應該具有 LOB 長度,而不是 1 或零。
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

// 連線等等。

$connectionLink = mysqli_connect( .... );

// 查詢等等。

$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