| この記事の要点 |
|
エラー内容
PHP 7 以降では、次のような Fatal error が出て処理が止まります。
Fatal error: Uncaught Error: Cannot use object of type stdClass as array in /path/to/file.php:12
メッセージを直訳すると「stdClass 型のオブジェクトを配列として使うことはできません」です。末尾のファイル名と行番号が、問題のアクセスをしている箇所です。
原因:オブジェクトに配列の書き方でアクセスしている
stdClass は PHP の汎用的な空のクラスで、プロパティを自由に追加できる「入れ物」です。見た目は連想配列に似ていますが、型としてはオブジェクトなので、要素の取り出し方が違います。
| データの型 | 正しいアクセス | 間違ったアクセス(エラーになる) |
|---|---|---|
| 連想配列(array) | $data['name'] | $data->name |
| オブジェクト(stdClass) | $data->name | $data['name'] |
つまり、$配列[インデックス] という扱いではなく、$stdClass->インデックス という扱いにすれば解決できます。
stdClass が返ってくる代表的な場面
自分で new stdClass() を書いた覚えがなくても、次のような関数・ライブラリが stdClass を返します。
json_decode($json): 第 2 引数を省略すると、JSON のオブジェクトは stdClass になる(最も多い原因)- PDO:
fetch(PDO::FETCH_OBJ)/fetchAll(PDO::FETCH_OBJ)で取得した行 - Laravel のクエリビルダ:
DB::table('users')->get()や->first()の各行は stdClass(Eloquent モデルとは別物) (object)$array: 配列をオブジェクトにキャストした結果- 外部 API の SDK など、レスポンスをオブジェクトで返すライブラリ
対処法
1. アロー演算子でアクセスする(基本)
$json = '{"name":"Taro","address":{"city":"Tokyo"}}';
$user = json_decode($json);
// NG: Cannot use object of type stdClass as array
// echo $user['name'];
// OK
echo $user->name; // Taro
echo $user->address->city; // Tokyo
キー名にハイフンなど識別子に使えない文字が含まれる場合は、波かっこで囲みます。
$obj = json_decode('{"first-name":"Taro"}');
echo $obj->{'first-name'}; // Taro
2. json_decode で最初から連想配列にする
配列として扱うコードがすでに多い場合は、デコード側を変えるのが一番影響が少なく済みます。
$user = json_decode($json, true); // 第 2 引数 true で連想配列
echo $user['name'];
echo $user['address']['city'];
// フラグで指定する書き方でも同じ
$user = json_decode($json, null, 512, JSON_OBJECT_AS_ARRAY);
3. 取得済みのオブジェクトを配列に変換する
// 1 階層だけ変換(ネストした中身は stdClass のまま)
$arr = (array)$user;
$arr2 = get_object_vars($user);
// ネストも含めて丸ごと変換
$deep = json_decode(json_encode($user), true);
(array) キャストは外側だけが配列になるため、$arr['address']['city'] と書くと、内側で同じエラーが再発します。ネストしている場合は json_encode → json_decode(..., true) の往復が簡単です。
4. PDO・Laravel の場合
// PDO: 連想配列で受け取る
$rows = $pdo->query('SELECT id, name FROM users')->fetchAll(PDO::FETCH_ASSOC);
echo $rows[0]['name'];
// Laravel クエリビルダ: 各行は stdClass なのでアローで読む
$users = DB::table('users')->get();
foreach ($users as $u) {
echo $u->name;
}
// どうしても配列が欲しい場合
$array = DB::table('users')->get()
->map(fn ($row) => (array)$row)
->all();
Eloquent モデル(User::find(1) など)は ArrayAccess を実装しているため $user['name'] でも読めますが、クエリビルダの結果は読めません。同じプロジェクト内で両方を使っていると混乱しやすいポイントです。
落とし穴
- 逆のエラー: 配列にアロー演算子を使うと、PHP 8 では「Attempt to read property "name" on array」という警告が出て値は null になります(PHP 7 では「Trying to get property of non-object」の Notice)。どちらの型かを確認してから書き換えましょう
- Blade やテンプレート内でも同じ:
{{ $item['name'] }}でエラーが出る場合、コントローラから渡しているのが stdClass の可能性があります - null の可能性: JSON が不正だと
json_decodeは null を返します。PHP 8 なら$user?->address?->cityのような nullsafe 演算子で安全に読めます - 配列関数に渡せない:
array_columnなどはオブジェクトの配列にも一部対応しますが、array_mergeなどは配列前提です。配列関数を多用するなら最初から連想配列で受け取る方が楽です
確認方法
変数の型が分からないときは、まず中身を表示して確認します。
var_dump($user);
// object(stdClass)#1 (2) { ... } と出たらオブジェクト
// array(2) { ... } と出たら配列
var_dump(is_object($user), is_array($user));
echo get_debug_type($user); // PHP 8: "stdClass" や "array"
Laravel なら dd($user) でも型が表示されます。表示結果が object(stdClass) ならアロー演算子、array なら角かっこ、と書き分けてください。
関連
- PHPでオブジェクトを配列に変換する方法|キャスト・get_object_vars・json
- PHP の配列|添字と連想配列・主要関数・in_array の落とし穴
- Laravel Query Builder の SELECT 完全ガイド
- JavaScript JSON (stringify / parse) 完全ガイド
子ページはありません
- Fatal error: Maximum execution time of 30 seconds exceeded in...
- Fatal error: Uncaught Error: Cannot use object of type stdClass as array in ...
- Warning: Use of undefined constant ... - assumed '...' (this will throw an Error)
- ERROR: Call to undefined method Maatwebsite\Excel\Excel::load()
- Maximum execution time of 30 seconds exceeded
- Your requirements could not be resolved to an installable set of packages. ... To enable extensions, verify that they are enabled in your .ini files:
- could not find driver
- the requested PHP extension mbstring is missing from your system.
- the requested PHP extension dom is missing from your system.
- A non well formed numeric value encountered
- Warning: Cannot modify header information - headers already sent by ...
- php_network_getaddresses: getaddrinfo failed: Name or service not known
- XMLWriter::openUri(): Unable to resolve file path
- Object of class stdClass could not be converted to string
- Class 'Google_Service_Youtube' not found
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスのソフト一覧|Blender・Metasequoiaと用途別の選び方
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Visual Studio「デザイナーを表示できません」エラーの原因と対処 2026-10-28 12:06:00
- SSH 認証に失敗しました。再試行してください の対処 2026-10-28 12:06:00
- SSH2 秘密鍵の読み込みに失敗しました の原因と対処 2026-10-28 12:06:00
- TeraTerm のよくあるエラーと対処法完全ガイド — Connection refused / 2026-10-28 12:06:00
- Visual Studio エラー一覧|コンパイルエラー・警告の確認方法と対処 2026-10-28 11:39:57
- Whitelabel Error Page の原因と消し方|Spring Boot のエラーページ 2026-10-28 11:39:57
- Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法 2026-10-28 11:39:57
- SQL WHERE 句完全ガイド 2026-10-28 11:39:57
- SQL JOIN 完全ガイド (INNER/LEFT/RIGHT/FULL OUTER) 2026-10-28 11:39:57
- tomcat の起動 / 停止ログと catalina.log・catalina.out の違い 2026-10-28 10:24:23
- Tomcat の起動確認方法 5 つ|localhost:8080・ポート・プロセス・ログ 2026-10-28 10:24:23
- Oracle 19c COMMITの使い方: 暗黙コミット・自動確定・応答不明時の確認 2026-10-28 09:59:09
- Oracle 19c DELETE文|削除対象の確認・COMMIT前の判断・ROLLBACKの条件 2026-10-28 09:59:09
- Oracle 19c INSERT文|INSERT ALL・SELECT・RETURNINGとMERGEの使い分け 2026-10-28 09:59:09
- Oracle 19cのトランザクション制御|COMMIT・ROLLBACK・分離レベルと接続設定 2026-10-28 09:59:09