2024 日本 PHP 研討會

執行語句

可以使用 mysqli::query()mysqli::real_query()mysqli::multi_query() 執行語句。mysqli::query() 函式是最常用的,它將執行語句與緩衝擷取其結果集(如果有的話)組合在一次呼叫中。呼叫 mysqli::query() 等同於先呼叫 mysqli::real_query(),然後再呼叫 mysqli::store_result()

範例 #1 執行查詢

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");

緩衝的結果集

語句執行後,結果可以一次全部擷取,或從伺服器逐行讀取。用戶端結果集緩衝允許伺服器盡早釋放與語句結果相關聯的資源。一般來說,用戶端消耗結果集的速度較慢。因此,建議使用緩衝的結果集。mysqli::query() 結合了語句執行和結果集緩衝。

PHP 應用程式可以在緩衝的結果中自由瀏覽。瀏覽速度很快,因為結果集保存在用戶端記憶體中。請記住,透過用戶端擴展通常比擴展伺服器更容易。

範例 #2 瀏覽緩衝的結果

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)");

$result = $mysqli->query("SELECT id FROM test ORDER BY id ASC");

echo
"反向排序...\n";
for (
$row_no = $result->num_rows - 1; $row_no >= 0; $row_no--) {
$result->data_seek($row_no);
$row = $result->fetch_assoc();
echo
" id = " . $row['id'] . "\n";
}

echo
"結果集排序...\n";
foreach (
$result as $row) {
echo
" id = " . $row['id'] . "\n";
}

以上範例將輸出

Reverse order...
 id = 3
 id = 2
 id = 1
Result set order...
 id = 1
 id = 2
 id = 3

未緩衝的結果集

如果客戶端記憶體資源不足,且不需要盡早釋放伺服器資源來保持伺服器負載低,則可以使用未緩衝的結果。在讀取所有資料列之前,無法滾動瀏覽未緩衝的結果。

範例 #3 瀏覽未緩衝的結果

<?php

$mysqli
->real_query("SELECT id FROM test ORDER BY id ASC");
$result = $mysqli->use_result();

echo
"結果集順序...\n";
foreach (
$result as $row) {
echo
" id = " . $row['id'] . "\n";
}

結果集值的資料類型

mysqli::query()mysqli::real_query()mysqli::multi_query() 函式是用於執行非預備語句。在 MySQL Client Server Protocol 層級,使用指令 COM_QUERY 和文字協定來執行語句。使用文字協定時,MySQL 伺服器會在傳送前將結果集的所有資料轉換為字串。無論 SQL 結果集欄位的資料類型為何,都會執行此轉換。 mysql 用戶端程式庫會以字串形式接收所有欄位值。不會進行進一步的用戶端轉換以將欄位轉換回其原生類型。相對地,所有值都以 PHP 字串提供。

範例 #4 文字協定預設返回字串

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))");
$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')");

$result = $mysqli->query("SELECT id, label FROM test WHERE id = 1");
$row = $result->fetch_assoc();

printf("id = %s (%s)\n", $row['id'], gettype($row['id']));
printf("label = %s (%s)\n", $row['label'], gettype($row['label']));

以上範例將輸出

id = 1 (string)
label = a (string)

如果使用 mysqlnd 函式庫,可以透過設定 MYSQLI_OPT_INT_AND_FLOAT_NATIVE 連線選項,將整數和浮點數欄位轉換回 PHP 數字。如果設定了此選項,mysqlnd 函式庫會檢查結果集的中繼資料欄位類型,並在 PHP 資料類型值範圍允許的情況下,將數值 SQL 欄位轉換為 PHP 數字。例如,如此一來,SQL INT 欄位將會以整數形式返回。

範例 #5 使用 mysqlnd 和連線選項的原生資料類型

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$mysqli = new mysqli();
$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1);
$mysqli->real_connect("example.com", "user", "password", "database");

$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))");
$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')");

$result = $mysqli->query("SELECT id, label FROM test WHERE id = 1");
$row = $result->fetch_assoc();

printf("id = %s (%s)\n", $row['id'], gettype($row['id']));
printf("label = %s (%s)\n", $row['label'], gettype($row['label']));

以上範例將輸出

id = 1 (integer)
label = a (string)

另請參閱

新增註釋

使用者貢獻的註釋

此頁面沒有使用者貢獻的註釋。
To Top