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 則註釋

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 迴圈,或者
//如果您懶得不想寫出每個要綁定的參數,這會很有用。
}
//繼續像往常一樣。
?>
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;

}
?>
piedone at pyrocenter dot hu
16 年前
我嘗試了提到的 stmt_bind_assoc() 函式,但不知何故,非常奇怪的是它不允許將值寫入陣列!在 while 迴圈中,資料列擷取正確,但如果我寫入 $array[] = $row;,陣列將會被資料集的最後一個元素填滿... 不幸的是,我找不到解決方案。
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);
}
?>
andrey at php dot net
19 年前
重要注意事項:當您將此函式用於大型結果集或 BLOB/TEXT 欄位時,請務必小心。當一個或多個欄位的類型為 (MEDIUM|LONG)(BLOB|TEXT) 且未呼叫 ::store_result() 時,mysqli_stmt_fetch() 將會嘗試為每個此類欄位配置至少 16MB 的記憶體。結果集中最長的值例如為 30 位元組也_無關緊要_,仍會配置 16MB。因此,在擷取大量資料時,使用參數綁定並不是最佳的作法。為什麼?因為資料會先儲存在記憶體中的 MySQL 結果集中,然後再次儲存在 PHP 變數中。
To Top