collect — 配列/反復可能を Collection に変換するヘルパー

helper
  • カテゴリ: helper
  • 掲載バージョン: Laravel 12・PHP 8.4
  • 名前空間 / FQCN / コマンド: collect(グローバル関数)
  • 関連: Collection::make / Collection::wrap / Arr::wrap / LazyCollection / cursor
  • 変更履歴: Laravel 5.2 追加/Laravel 6.x で LazyCollection 登場(大規模データは併用推奨)

要点(TL;DR)

  • 配列・iterable・Generator 等を Illuminate\Support\Collection に変換するための最短手段。
  • 最低限の使い方:collect([1, 2, 3])->sum();
  • よくある罠
    • 既に Collection の値をさらに配列で包んで collect([$collection]) としてしまい二重ラップになる
    • 巨大配列に対して collect() → 全件メモリ載せで O(n) メモリ消費
    • Generator を渡すと反復を消費(使い切り)する

概要

collect() は Laravel のグローバルヘルパーで、与えた値を Illuminate\Support\Collection として扱えるようにします。チェーンメソッドでの加工・集計・絞り込みを可能にし、配列中心のコードを読みやすく保守しやすい形へ移行できます。フォーム入力、API 応答、設定配列など、あらゆるデータの“入り口”でまず collect() しておくと後続処理が簡潔になります。

構文 / シグネチャ

/**
 * Convert the given value to a Collection.
 *
 * @param  mixed  $value  // array | iterable | Traversable | Generator | JsonSerializable | Collection | null
 * @return \Illuminate\Support\Collection
 */
function collect($value = null);
  • 引数(表)
引数必須既定値説明
$valuemixedいいえnull変換対象。配列、iterableTraversable/GeneratorJsonSerializable、既存の Collectionnull を受け付ける
  • 戻り値Illuminate\Support\Collection インスタンス
  • 例外/副作用:例外は通常なし。Generator/Iterator を渡すと反復を消費して配列化される(使い切り)。

使用例

最小例

<?php

use Illuminate\Support\Collection;

$sum = collect([1, 2, 3])
    ->map(fn ($n) => $n * 2)
    ->sum();          // 12

// $sum は 12

実務例(フォーム配列の正規化と重複排除)

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Collection;

function normalizedTags(Request $request): Collection
{
    // "tags" は文字列/配列/カンマ区切りなど混在がありえる想定
    $raw = $request->input('tags');

    return collect(is_string($raw) ? explode(',', $raw) : $raw)
        ->filter()                     // null/空文字を除外
        ->map(fn ($t) => trim($t))     // 前後空白除去
        ->map(fn ($t) => mb_strtolower($t))
        ->unique()
        ->values();                    // 連番キーに詰め直し
}

実務例(API 応答の配列を DTO に変換)

<?php

use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;

final class ItemDto
{
    public function __construct(
        public int $id,
        public string $name,
        public int $price,
    ) {}
}

function fetchItems(): Collection
{
    $items = Http::timeout(5)->get('https://example.com/api/items')->json();

    return collect($items)
        ->where('active', true)
        ->map(fn ($r) => new ItemDto($r['id'], $r['name'], $r['price']))
        ->sortBy('price')
        ->values();
}

よくある落とし穴・注意

  • 二重ラップ:既に Collection のものをさらに配列で包んで collect([$collection]) とすると、[Collection] という1要素コレクションになります。collect($collection) とするか、そのまま $collection を使う。
  • メモリ消費collect() は標準 Collection を返すため全件をメモリに載せます。レコード大量処理は LazyCollection や Eloquent の cursor() / chunk() を使う。
  • 入力の変更影響collect() は新しいオブジェクトを返すので元の配列は変更されません。ただし要素がオブジェクトなら参照先は同じため、オブジェクト内部は共有されます。
  • Generator の消費Generator を渡すとその場で展開→消費されるため、再利用はできません。ストリーミング処理を保ちたい場合は LazyCollection::make() を検討。

代替・関連APIとの比較

  • Collection::make($value)collect() と等価。明示的に静的メソッドで書きたい場合に。
  • Collection::wrap($value) / Arr::wrap($value):単一値を必ず配列化(空は空配列)。コレクションチェーン不要なら Arr::wrap が軽量。
  • LazyCollection / lazy():巨大データを遅延評価で処理。メモリフットプリントを最小化したいときはこちら。
  • Eloquent cursor():DB レコードをカーソルで取り出す LazyCollection。全件読み込みを避けたい集計に最適。

選定基準
「即座に全件をメモリに載せて加工する」→ collect()Collection::make
「値をとりあえず配列に包みたい」→ Arr::wrap
「大量データをストリーム処理」→ LazyCollectioncursor()chunk()

テスト例(Pest)

<?php

use Illuminate\Support\Collection;

it('normalizes tag inputs', function () {
    $tags = collect([' PHP ', 'php', null, 'Laravel'])
        ->filter()
        ->map(fn ($t) => trim($t))
        ->map(fn ($t) => mb_strtolower($t))
        ->unique()
        ->values();

    expect($tags)->toBeInstanceOf(Collection::class)
                 ->and($tags->all())->toBe(['php', 'laravel']);
});

トラブルシュート(エラー別)

症状/エラー原因対処
call to member function map() on array配列に直接コレクションメソッドを呼んでいる先頭で collect($array) に変換
結果が [[...]] のように一段深いcollect([$collection]) で二重に包んだcollect($collection) または $collection をそのまま使う
メモリ不足 / 処理が重い全件を collect() で読み込んだcursor() / chunk() / LazyCollection を利用
2回目以降の反復で空になるGeneratorcollect() 済みで消費必要に応じて LazyCollection::make($generator) を用いる

参考リンク

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする