#29 Laravel基礎

Collectionを使いこなす

Collectionとは

Eloquentの get() はデータベースの結果をCollectionオブジェクトとして返します。CollectionはPHPの配列を強化したもので、流暢(fluent)なメソッドチェーンでデータを処理できます。


基本のメソッド

map — 各要素を変換する

$posts = Post::all();

// 全タイトルをUpperCaseに変換
$titles = $posts->map(fn ($post) => strtoupper($post->title));

filter — 条件に合う要素だけ残す

// 公開済みの投稿だけ
$published = $posts->filter(fn ($post) => $post->status === 'published');

// filter() の後は keys がずれるので values() でリセット
$published = $posts->filter(...)->values();

each — 各要素に処理を実行する

$posts->each(function ($post) {
    Cache::forget("post:{$post->id}");
});

絞り込みと検索

// where() は filter() の糖衣構文
$published = $posts->where('status', 'published');

// first() で最初の1件
$latest = $posts->first();

// firstWhere() で条件に合う最初の1件
$featured = $posts->firstWhere('is_featured', true);

// contains() で存在確認
$hasLaravel = $posts->contains(fn ($p) => str_contains($p->title, 'Laravel'));

集計

// 件数
$count = $posts->count();

// 合計
$totalViews = $posts->sum('view_count');

// 平均
$avgViews = $posts->avg('view_count');

// 最大・最小
$max = $posts->max('view_count');
$min = $posts->min('view_count');

並び替えと整形

// view_count の多い順に並び替え
$ranked = $posts->sortByDesc('view_count')->values();

// 昇順
$oldest = $posts->sortBy('created_at')->values();

// 先頭N件・末尾N件
$top3 = $posts->take(3);
$last3 = $posts->takeLast(3);

// 重複削除
$unique = $posts->unique('user_id');

グループ化

// カテゴリーでグループ化
$grouped = $posts->groupBy('category');
// 結果: ['Laravel' => Collection, 'PHP' => Collection, ...]

foreach ($grouped as $category => $categoryPosts) {
    echo "{$category}: {$categoryPosts->count()}件\n";
}

reduce — 集計・変換

// 全投稿のview_countの合計(sumと同等だが任意の処理に使える)
$totalViews = $posts->reduce(fn ($carry, $post) => $carry + $post->view_count, 0);

pluck — 特定のカラムだけ取り出す

// タイトルだけの配列
$titles = $posts->pluck('title');
// → Collection ['Laravel入門', 'PHP基礎', ...]

// IDをキー、タイトルを値にした配列
$titleById = $posts->pluck('title', 'id');
// → Collection [1 => 'Laravel入門', 2 => 'PHP基礎', ...]

mapWithKeys — キーと値を変換する

// [id => title] の形に変換
$result = $posts->mapWithKeys(fn ($post) => [
    $post->id => $post->title,
]);

lazy コレクション(大量データに対応)

大量のレコードを一括でメモリに読み込まず、少しずつ処理したい場合:

// 全投稿を1000件ずつ処理(メモリ節約)
Post::cursor()->each(function (Post $post) {
    // 1件ずつ処理
});

// lazy() と chunk() の組み合わせ
Post::lazy(1000)->each(function (Post $post) {
    // 1000件ずつ内部的に取得しながら処理
});

配列への変換

// Collection を通常の配列に変換
$array = $posts->toArray();

// JSON文字列に変換
$json = $posts->toJson();

まとめ

  • CollectionはEloquentの get() が返す配列の強化版
  • map(), filter(), groupBy() などのメソッドをチェーンできる
  • pluck() で特定カラムだけ取り出せる
  • 大量データには cursor()lazy() でメモリを節約できる

次回(最終回)はデプロイとパフォーマンスチューニングを学びます。