報錯 Cannot use object of type stdClass as array 核心原因:**嘗試用陣列語法 $obj['key'] 訪問物件屬性**。PHP 中物件屬性必須用 $obj->key 或 $obj->{'key'} 訪問。常見於 json_decode() 默認返回物件、PDO::FETCH_OBJ、SoapClient 返回、自定義類實例。
典型觸發場景
<?php
$json = '[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]';
$data = json_decode($json); // 默認返回 stdClass 物件陣列
// ❌ 錯誤寫法
echo $data[0]['name']; // Fatal error: Cannot use object of type stdClass as array
// ✅ 正確寫法
echo $data[0]->name; // Alice
// ✅ 方案二:json_decode 第二參數 true 強制返回關聯陣列
$data = json_decode($json, true);
echo $data[0]['name']; // Alice,正常
?>
兩種修復方案對比
| 方案 | 代碼 | 優點 | 缺點 |
| 改用物件語法 | $obj->property | 無需改動數據結構、記憶體略省(物件比陣列小)、保留類型提示 | 需修改所有訪問點、IDE 重構支援較好 |
| json_decode(..., true) | json_decode($json, true) | 最小改動(僅解析處)、習慣陣列操作、兼容舊代碼 | 大數據集記憶體稍高、失去物件方法/類型 |
更多來源場景與修復
| 來源 | 返回類型 | 修復 |
| json_decode() | stdClass | json_decode($json, true) 或 ->prop |
| PDOStatement::fetch(PDO::FETCH_OBJ) | stdClass | 改用 PDO::FETCH_ASSOC 或 ->col |
| SoapClient 方法返回 | stdClass | ->PropertyName(注意大小寫) |
| MongoDB 查詢 | MongoDB\Model\BSONDocument | 實現 ArrayAccess,實際支援 ['key'],但建議 ->key |
| 自定義類實例 | YourClass | 必須 ->property,除非實現 ArrayAccess 接口 |
調試技巧:快速識別變量類型
<?php
var_dump($data);
// 輸出示例:
// array(2) {
// [0]=>
// object(stdClass)#1 (2) { ["id"]=> int(1) ["name"]=> string(5) "Alice" }
// [1]=>
// object(stdClass)#2 (2) { ["id"]=> int(2) ["name"]=> string(3) "Bob" }
// }
// 關鍵標識:object(stdClass)#1 → 必須用 -> 訪問
// gettype() / get_class() / instanceof
echo gettype($data[0]); // object
echo get_class($data[0]); // stdClass
var_dump($data[0] instanceof stdClass); // true
?>
最佳實踐建議
- API 契約明確:團隊約定內部傳遞統一用陣列(
json_decode(..., true)),對外輸出才轉物件/JSON。
- DTO 物件:關鍵業務實體定義具體類
class User { public int $id; public string $name; },享受 IDE 提示、靜態分析、類型安全。
- 統一轉換層:Repository/Service 層統一
json_decode(..., true),Controller 僅處理陣列。
- 異常處理:封裝
safe_json_decode($json, true) 捕獲 JsonException (PHP 7.3+)。