這是 PHP 開發中極高頻的錯誤:Cannot use object of type stdClass as array。當嘗試用陣列語法 $obj['key'] 存取物件屬性時觸發。本文解析產生原因、兩種標準解法,並延伸介紹物件與陣列互轉的最佳實務。
<?php
$json = '[{"id":1,"title":"文章一"},{"id":2,"title":"文章二"}]';
$data = json_decode($json); // 預設回傳 stdClass 物件陣列
// 錯誤寫法
echo $data[0]['title']; // ❌ Fatal Error: Cannot use object of type stdClass as array
// 正確寫法
echo $data[0]->title; // ✅ 輸出:文章一
json_decode($json, true) 直接產生關聯陣列 (最推薦)$data = json_decode($json, true); // 第二參數 true = associative array
echo $data[0]['title']; // ✅ 正常運作
// 結構:[ ['id'=>1,'title'=>'文章一'], ['id'=>2,'title'=>'文章二'] ]
優點:直接得到陣列,後續處理統一使用陣列語法,無需物件轉換。
$obj->propertytitle; // ✅
// 甚至可鏈式存取
echo $data[0]->title . ' - ID: ' . $data[0]->id;
適用場景:需要利用物件特性(如方法、型別提示、序列化行為)時。
<?php
/**
* 任意物件/陣列 深度轉換為純陣列
* @param object|array $data
* @return array
*/
function toArray($data) {
if (is_object($data)) $data = (array) $data;
if (!is_array($data)) return [$data];
return array_map(function($v) {
return is_object($v) || is_array($v) ? toArray($v) : $v;
}, $data);
}
/**
* 陣列深度轉換為 stdClass 物件
* @param array $arr
* @return object
*/
function toObject($arr) {
if (!is_array($arr)) return $arr;
$obj = new stdClass();
foreach ($arr as $k => $v) {
$obj->$k = is_array($v) ? toObject($v) : $v;
}
return $obj;
}
// 使用範例
$objData = json_decode($json);
$arrData = toArray($objData); // 物件樹 → 陣列樹
$objAgain = toObject($arrData); // 陣列樹 → 物件樹
| 來源 | 回傳型別 | 建議處理 |
|---|---|---|
json_decode() | stdClass / array | 習慣加 true 參數 |
SoapClient 回應 | stdClass | 用 toArray() 統一轉陣列處理 |
SimpleXMLElement | 物件 | json_decode(json_encode($xml), true) 快速轉陣列 |
| PDO::FETCH_OBJ | stdClass | 改用 PDO::FETCH_ASSOC 直接拿陣列 |
| MongoDB 驅動 | 物件 | 驅動選項 typeMap 設定陣列模式 |