BLOG

ブログ

【Laravel】EloquentとCollectionを理解する

はじめに

今までフロントエンドの開発を中心に取り組んできましたが、直近の案件で初めて Laravel に触れることになりました。

業務を進める中で「これは何だ…?!」と感じた部分がいくつかあるのですが、その中でも特に印象に残ったのが CollectionEloquent です。
この記事では、上記について理解したことを初心者目線で簡単にまとめておきたいと思います。

Collectionとは?

LaravelのCollectionとは、簡単には下記のようなものです。

  1. 複数のデータを格納するための入れ物であり、リスト形式でデータを扱えるラッパークラス
  2. 内部的には配列を保持しているが、単なる配列とは異なりIlluminate\Support\Collection クラスのインスタンスとして提供される
  3. 多数の便利なメソッドが用意されている点

③については、従来であればループや条件分岐を組み合わせて数行記述していた処理を短いコードで簡潔に表現できるのでめちゃ便利です(参考: Laravel公式ドキュメント

上記のように、Collectionは「配列をラップしたオブジェクト」であり、配列にはない柔軟な操作を可能にしています。

Collectionに関して戸惑ったこと

Laravelを見始めた当初は、配列と違う?単数じゃないときはこれを使うであってる?と戸惑っていました。が、調べたりChatGPTにまとめてもらった表で理解しました。

圧倒的に使いやすそうというのが伝わってきます。

また、実際Collectionのデータ形式ってどんな感じ?という例が↓です。

use Illuminate\Support\Collection;

$collection = collect([
    ['id' => 1, 'name' => 'Taro'],
    ['id' => 2, 'name' => 'Hanako'],
]);

この $collection の中身は「配列の配列」に見えますが、型としてはCollectionインスタンスになっています。

Collectionと配列の使い分けについて

Collectionと配列の違いについてなんとなくわかったものの、どう使い分けたらよいのか?という点について簡単にまとめてみました。

💡Collectionを使う場面

  • EloquentでDBからデータを取得したとき(デフォルトでCollectionになる)
  • データを「フィルタリング」「変換」「集約」などしたいとき
  • mapgroupByのような操作をチェーンして読みやすくしたいとき

💡配列を使う場面

  • 単純にキーと値を持たせるだけの軽量な用途
  • フレームワーク外のPHP組み込み関数を多用するとき
  • パフォーマンス重視で「超大量データ」を処理する場合

基本的にはLaravelプロジェクト内ではCollectionを優先し、「外部ライブラリや標準PHPとのやりとりが必要なとき」だけ配列に変換する(->toArray())のがちょうどいい使い分け方のようです。

🌟 Collectionまとめ

  • Collection は配列をオブジェクトでラップしたもの
  • 内部は配列だが、便利なメソッドが山ほど使える
  • 配列に比べて 宣言的にデータ処理を書ける(クエリビルダ的な感覚に近い)
  • 最終的に ->toArray()->all() で配列に戻すことも可能

Eloquentとは?

Eloquentは、Laravelに備わっているORM(オブジェクトリレーショナルマッピング)という仕組みで、DB操作を簡単にしてくれるものです。

通常DBにアクセスするときはSQLを書く必要がありますが、Eloquentを使えばモデルというDBテーブルに対応したクラスを通じて、レコードの取得・新規追加・更新・削除といった操作ができるようになります。

また、モデルには他テーブルとのリレーションを定義出来るため、モデルに関連テーブルを設定することで、複数テーブルにまたがるデータ取得もシンプルに書けてとても便利です。

特徴的なのは、DBのレコードをオブジェクトとして扱えるという点です。これにより、PHPのコードだけで直感的にデータを操作できるようになります。

上記のように、EloquentはSQLを意識せず、オブジェクト思考的にDBを扱える便利な仕組み となっています。

📌 配列やCollectionとの違い

前述のCollectionとの違いをまとめてみました。

  • 配列: 単なるデータの集まり
  • Collection: Laravelが用意する、便利メソッド付きのデータの集まり
  • Eloquentモデル: テーブルの1レコードを表すオブジェクト

例えば、User::all() は「EloquentモデルのCollection」を返します。
配列のようにループでき、Collectionの便利なメソッドも使えて、各要素はモデルとして操作できます。

混乱したこと

プロジェクトで実装中にうまくいかない箇所があり、原因をよく見てみると気付いたことがあります。

なんかよく見たら Illuminate\Support\Collection と Illuminate\Database\Eloquent\Collection とでCollectionがふたつあるけど、これなにがどう違うん…?!

ということで、違いを下記にまとめました。

2種類のCollectionの違い

LaravelにはCollectionが2種類あります。

📌 Illuminate\Support\Collection

  • 普通のCollection
  • 配列のように扱える便利なメソッドが揃った汎用データの集まり
  • collect()で作れる
  • DBのモデルに限らず、どんな配列でも使える
$collection = collect([1,2,3]);
$collection->map(fn($n) => $n*2);

📌 Illuminate\Database\Eloquent\Collection

  • Eloquentモデル専用のCollection
  • Eloquentモデルの集まりを扱うために拡張されたCollection
  • User::all() などで返ってくる
  • 各要素はモデルなので、DB操作も可能
$users = User::all(); // Eloquent\Collection
$users->first()->update(['name'=>'Alice']);

つまり、Eloquent\Collection は Support\Collection を拡張したもので、各要素がモデルとして扱える!ということでした。

ややこしや

ここでややこしいのが、両者で使えるメソッドは名前が同じでも、Eloquentは「DBアクセス用」・「Collectionは「メモリ上のデータ操作用」となっているので、「どの段階で動くか」「返り値の方がなにか」が違っており、チェーンや扱い方が微妙に変わるというところです。

なので注意ポイントを下記にまとめてみました。

💡 ポイント

  1. DBにアクセスする前か後かを意識する
  2. Eloquent → Collection → 配列 の流れを頭に入れる(EloquentでSQLを組み立て、getやallで実行するとCollectionとして結果が返り、必要に応じてtoArrayで配列に変換する流れ)
  3. 名前は同じでも「Eloquent用かCollection用か」を公式ドキュメントで確認する

おわり

Laravelはまだまだわからないことだらけ&せっかく触れた技術ということで今後も継続して学習していこうと思います!