執行 SELECT 查詢後,需將 mysqli_result 物件逐行轉為可用資料。PHP 提供兩種主流風格:物件導向(fetch_object)與陣列導向(fetch_array/fetch_assoc)。本文對比兩者用法、效能與適用場景。
$sql = "SELECT name, brief FROM cars";
$result = $mysqli->query($sql);
while ($row = $result->fetch_object()) {
echo $row->name . ' - ' . $row->brief . "
";
}
// 欄位名即物件屬性,語意清晰,適合領域模型映射
stdClass 物件,屬性名 = 欄位名(區分大小寫)。$row->name 類似實體屬性存取。fetch_object('CarEntity') 直接映射到自訂類別(需類別屬性為 public 或有 __set)。$sql = "SELECT name, brief FROM cars";
$result = $mysqli->query($sql);
// 1. 數字索引 + 關聯索引(預設 MYSQLI_BOTH)
while ($row = $result->fetch_array()) {
echo $row[0] . ' - ' . $row[1] . "
"; // 數字索引
echo $row['name'] . ' - ' . $row['brief'] . "
"; // 關聯索引
}
// 2. 僅關聯索引(推薦,節省記憶體)
while ($row = $result->fetch_assoc()) {
echo $row['name'] . ' - ' . $row['brief'] . "
";
}
fetch_array(MYSQLI_ASSOC) 等同 fetch_assoc(),僅返回關聯陣列,記憶體佔用較小。fetch_array(MYSQLI_NUM) 僅返回數字索引陣列。json_encode、array_map 等陣列函式處理。| 指標 | fetch_object | fetch_assoc |
|---|---|---|
| 記憶體/行 | 略高(物件開銷) | 較低 |
| CPU 時間 | 略慢 | 略快 |
| 程式碼可讀性 | 高(屬性存取) | 中(鍵名字串) |
| 適用場景 | 領域模型、ORM 映射、結構固定 | 通用腳本、API 回傳 JSON、動態欄位 |
實際專案中差異微小,**建議統一團隊風格**;若需高效能大量資料處理,考慮
fetch_assoc+ 生成器(yield)逐行處理避免佔滿記憶體。
function queryAll($mysqli, $sql) {
$res = $mysqli->query($sql);
if ($res === false) throw new Exception($mysqli->error);
if (!$res instanceof mysqli_result) return []; // 非 SELECT
$data = [];
while ($row = $res->fetch_assoc()) { // 或 fetch_object()
$data[] = $row;
}
$res->free(); // 釋放結果集記憶體
return $data;
}
// 預處理多條 SQL(如 CALL stored_proc() 返回多個結果集)
$mysqli->multi_query("CALL get_dashboard_data()");
do {
if ($res = $mysqli->store_result()) {
while ($row = $res->fetch_assoc()) { /* 處理第 1 個結果集 */ }
$res->free();
}
} while ($mysqli->more_results() && $mysqli->next_result());