Laravelには配列を扱いやすくする"Collection"というものが存在します。
今回は、Collectionの基本的な操作について解説します。
(参考) https://readouble.com/laravel/10.x/ja/collections.html
解説
Collectionとは一言で言うと、配列を扱いやすくするラッパーのことです。
シンプルな配列データから複雑なモデルオブジェクトなどのデータを簡単に扱うことができるようになります。
Collectionを使うとどう便利になるのか、配列との違いを例を使って説明します。
Collectionを使った配列操作例
まず、以下の配列があるとします。
$users = [
['name' => 'Taylor', 'age' => 30],
['name' => 'Abigail', 'age' => 25],
['name' => 'James', 'age' => 31],
];
PHPこの配列を操作して、ageが26以上の配列のnameだけで構成された配列を返すようにする場合以下のようになります。
どちらも同じ結果が得られますが、比較的読みやすい簡潔なコードでデータを操作できるのがCollectionです。
[Collectionを使わない場合]
$filteredNames = array_filter($users, function ($user) {
return $user['age'] >= 26;
});
$names = array_column($filteredNames, 'name');
dump($names);
↓出力結果
//array:2 [
// 0 => "Taylor"
// 1 => "James"
//]
PHP[Collectionを使う場合]
$names = collect($users)
->where('age', '>=', 26)
->pluck('name');
dump($names->all());
//array:2 [
// 0 => "Taylor"
// 1 => "James"
//]
PHPさらに、以下のような配列の中に配列があるようなデータ構造でも、先ほどとほぼ同じような処理で簡単に抽出することができます。
$users = [
['profile' => ['name' => 'Taylor', 'details' => ['age' => 30]]],
['profile' => ['name' => 'Abigail', 'details' => ['age' => 25]]],
['profile' => ['name' => 'James', 'details' => ['age' => 31]]]
];
PHP先ほどとの違いは、キーであるprofileを起点に配下のキーにアクセスするためにドット記法を使っているところです。
ですので、これで下の階層のキーで選別できるようになります。
use Illuminate\Support\Collection;
$names = (new Collection($users))
->where('profile.details.age', '>=', 26)
->pluck('profile.name');
dump($names->all());
//array:2 [
// 0 => "Taylor"
// 1 => "James"
//]
PHPModelを使ったCollection操作
今度はLaravelのEloquentを使ったModelの操作をCollectionの観点で見ていきます。
例えば、Userモデルをgetで取得すると、以下のような結果が得られます。
getメソッドは最初から各種レコードをCollectionの形式で取得していることがわかります。
$users = User::get();
dump($users);
// Illuminate\Database\Eloquent\Collection {
// all: [
// App\Models\User {#7083
// id: 1,
// name: "テストユーザー",
// email: "***@test.com",
// },
// ...
// ]
// }
PHPさらにここから条件を絞る場合は、where句を使って対象のテーブルのカラムの値で選別して取得できるようになります。
選別した場合、データが1つでもget()を使っている場合はCollectionの形式となります。
$users = App\Models\User::where('name', 'テストユーザー')->get();
dump($users);
// 以下のデータのみ抽出
// Illuminate\Database\Eloquent\Collection {
// all: [
// App\Models\User {#7083
// id: 1,
// name: "テストユーザー",
// email: "***@test.com",
// }
// ]
// }
PHP最後にリレーション関係にあるモデルを条件を絞って取得する場合についてです。
最初の配列の中に配列が入ったものをドット記法で操作する例を示しましたが、モデルオブジェクトの場合、リレーション関係にあるものがそれに当たる構造かと思います。
リレーション先のテーブルのカラムの値で絞る場合はwhereHas句を使います。
さらにリレーション先のテーブルのさらにリレーション先のテーブルのカラムで絞る場合は、以下のようにwhereHas句の中でドット記法で指定します。
以下はChatRoomに所属しているChatMemberのUserのnameで条件を絞り、ヒットしたChatRoomのみを取得するコードになります。
$chatRooms = App\Models\ChatRoom::whereHas('chatMembers.user', function ($query) {
$query->where('name', 'テストユーザー');
})->get();
PHP以上がCollectionについての解説でした。
今回はあくまでCollectionについての基本的な説明でしたので、別な記事にてCollectionを扱う上で便利なメソッドなどについて解説する記事も投稿したいと思います。