8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Laravel】コレクションのプロパティ取得ではまった話

Last updated at Posted at 2020-12-19

・2020/12/20 更新:コメントにてご指摘をいただき、内容を修正しました。

経緯

Laravelのコレクションを使用し、以下のようにアローでプロパティを指定し取り出そうとしたところ、うまく動作しなかった。

$user = collect([
    'name' => 'Yuta',
    'age' => 8
]);

print($user->name);
// ERROR: Property [name] does not exist on this collection instance

$usercollectヘルパで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')

おわりに

コメントでご指摘いただき、連想配列とオブジェクトをしっかり差別化して使うことが必要だと感じた。
コレクションについてもさらに理解を深めたい。

8
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?