在 PHP 早期開發中,操作 MySQL 資料庫時經常會用到 mysql_fetch_row、mysql_fetch_assoc、mysql_fetch_array 以及 mysql_fetch_object 這四個函數。雖然 mysql_* 系列函數已在 PHP 7.0 中被移除(建議改用 PDO 或 MySQLi),但理解它們的差異對於維護舊專案、閱讀歷史代碼仍具參考價值。本文將詳細對比這四個函數的返回結構、取值方式及適用場景。
mysql_fetch_row() 從結果集中取得一行,以枚舉數組(數字索引)形式返回。陣列鍵名從 0 開始遞增,對應欄位順序。無法使用欄位名稱作為鍵名取值。
while ($row = mysql_fetch_row($res)) {
// $row['cid'] 取不到值(報錯或為 null)
// $row[1] 可正常取得第二欄資料
echo $row[1] . '<br>';
}
特點:記憶體佔用最小,速度最快;但可讀性差,需記住欄位順序,維護困難。
mysql_fetch_assoc() 返回關聯數組,鍵名為欄位名稱,值為對應資料。無法使用數字索引取值。
while ($row = mysql_fetch_assoc($res)) {
// $row[1] 取不到值
// $row['cid'] 可正常取得 cid 欄位資料
echo $row['cid'] . '<br>';
}
特點:語義清晰,代碼可讀性強;但比 mysql_fetch_row 稍佔記憶體。
mysql_fetch_array() 預設返回同時包含數字索引和關聯索引的陣列(即 MYSQL_BOTH 模式)。也可通過第二參數指定模式:MYSQL_NUM(同 row)、MYSQL_ASSOC(同 assoc)、MYSQL_BOTH(預設)。
while ($row = mysql_fetch_array($res)) {
// 兩種方式均可取值
echo $row['cid'] . ' === ' . $row[1] . '<br>';
}
特點:彈性最大,兼容兩種取值習慣;但預設模式下陣列大小為其他兩者兩倍,記憶體佔用最高。建議明確指定模式以節省資源。
mysql_fetch_object() 將行數據封裝為 stdClass 物件,欄位名成為物件屬性。只能透過 -> 操作符存取。
while ($row = mysql_fetch_object($res)) {
echo $row->cid . ' >>> ' . $row->title . '<br>';
}
特點:符合物件導向風格,配合類映射(如 PDO::FETCH_CLASS)極其強大;但無法像陣列那樣遍歷鍵值。
| 函數 | 返回類型 | 鍵名類型 | 取值語法 | 記憶體佔用 | 推薦場景 |
|---|---|---|---|---|---|
| mysql_fetch_row | 陣列 | 純數字索引 | $row[0] | 最低 | 高效能、欄位固定、不需語義化的簡單腳本 |
| mysql_fetch_assoc | 陣列 | 純關聯鍵名 | $row['field'] | 中等 | 大多數業務邏輯,代碼可讀性優先 |
| mysql_fetch_array | 陣列 | 雙模式(預設) | $row[0] / $row['field'] | 最高(預設) | 需同時支援新舊代碼風格,或明確指定模式時 |
| mysql_fetch_object | 物件 | 物件屬性 | $row->field | 中等 | 物件導向架構、ORM 映射、結構化資料處理 |
新專案請使用 PDO 或 MySQLi:
PDOStatement::fetch(PDO::FETCH_ASSOC) 對應 mysql_fetch_assocPDOStatement::fetch(PDO::FETCH_NUM) 對應 mysql_fetch_rowPDOStatement::fetch(PDO::FETCH_BOTH) 對應 mysql_fetch_arrayPDOStatement::fetch(PDO::FETCH_OBJ) 對應 mysql_fetch_objectPDOStatement::fetch(PDO::FETCH_CLASS, 'MyClass') 直接映射到自定義類理解這些差異不僅能幫助維護舊代碼,也能在選擇現代 API 獲取模式時做出更精準的決策。