| この記事の要点 |
|
エラー内容
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 / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- プロジェクトをTomcatプロジェクトとして認識させる方法 2026-10-07 22:32:50
- MySQLの1366 Incorrect string value|Laravelの文字コード・絵文字エラー 2026-10-07 21:54:03
- curlの証明書ホスト名不一致|旧エラー51・現行60の確認と対処 2026-10-07 21:54:03
- LaravelのMassAssignmentException|fillableの原因と安全な対処 2026-10-07 21:54:03
- Eclipse で Tomcat の起動ログがコンソールに出ない時の確認手順 2026-10-07 21:54:02
- MySQLにおける中央値(Median)の導き方(バージョン8未満) 2026-10-07 13:49:45
- getInputForward 2026-10-07 13:41:15
- JSONから配列に変換 2026-10-07 13:41:15
- ビューから値をモデルに格納しコントローラーで受け取る方法 2026-10-07 13:23:41
- Laravelのテーブル作成と定義変更|マイグレーション・up/down・注意点 2026-10-07 13:23:41
- NumPy 配列に要素を追加する方法 (append / concatenate) 2026-10-07 13:23:41
- MariaDB・MySQLで現在日時を取得する方法|NOW・タイムゾーン・保存型 2026-10-07 13:13:36
- 【django】テンプレートで定数を使用する方法 2026-10-07 13:10:15
- Spring BootにおけるApplication.propertiesの環境依存設定の分割方法 2026-10-07 12:09:35
- Not supported for DML operations【Springエラー】 2026-10-07 11:09:38