・2020/12/20 更新:コメントにてご指摘をいただき、内容を修正しました。
経緯
Laravelのコレクションを使用し、以下のようにアローでプロパティを指定し取り出そうとしたところ、うまく動作しなかった。
$user = collect([
'name' => 'Yuta',
'age' => 8
]);
print($user->name);
// ERROR: Property [name] does not exist on this collection instance
$userはcollectヘルパでIlluminate\Support\Collectionインスタンスが返っているはずだから、
アローでキー指定して取り出せるのでは?と思ったのだが、どうもそうはいかないらしい。
調査
とりあえず$userの情報を見てみることに。
print_r($user);
/*
Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[name] => Yuta
[age] => 8
)
)
*/
Illuminate\Support\Collectionインスタンスではあるっぽい。
(2020/12/20 追記)
[items:protected] => Arrayとあるように中身が連想配列なのが原因とのこと。
仮にcollectヘルパではなく、Eloquentモデルで
App\Models\SampleModel::where('id', 1)->get()のように取得したデータの場合は、
中身はApp\Models\SampleModelオブジェクトの配列なので、
foreach ($users as $user) {
echo $user->name;
}
のようにforeachで回してオブジェクトに対してプロパティの指定ができる。
結論
collectヘルパを使って、更にアローでプロパティを指定したい場合は、
連想配列をオブジェクトに変換し、それを配列に入れてあげれば、
以下のようにforeachで回してオブジェクトに対してプロパティの指定ができる。
$users = collect([
(object)['name' => 'Yuta', 'age' => 8]
]);
foreach ($users as $user) {
echo $user->name;
}
ただ、そこまでしなくても以下のようにCollectionクラスのメソッドの恩恵を素直に受けた方が良さそう。
$user = collect([
'name' => 'Yuta',
'age' => 8
]);
$user->get('name')
おわりに
コメントでご指摘いただき、連想配列とオブジェクトをしっかり差別化して使うことが必要だと感じた。
コレクションについてもさらに理解を深めたい。