where — 条件で要素を抽出

collection
  • カテゴリ: collection
  • 掲載バージョン: Laravel 12・PHP 8.4
  • 名前空間 / FQCN / コマンド: Illuminate\Support\Collection::where
  • 関連: whereStrict / firstWhere / whereIn / whereBetween / filter
  • 変更履歴: 特記事項なし

要点(TL;DR)

  • 指定キーと値(や比較演算子)でコレクションを絞り込む
  • 最小: $filtered = collect($items)->where('active', true);
  • 罠: 「==」のゆるい比較キーは保持values()で再採番)/巨大データはDBで絞る

概要

where はコレクション内の配列・オブジェクトから条件に合致する要素だけを返します。ゆるい比較(==)が既定で、>・>=・<・<=・!= などの演算子も利用可能です。ドット記法でのネストアクセスに対応し、チェーンして複数条件を積み上げられます。結果は新しいコレクションで返り、元は変更しません。

構文 / シグネチャ

public function where(string|int $key, mixed $operatorOrValue, mixed $value = null): static;
// 使い方の実態: 
// where('status', 'active')              // '='(ゆるい比較)
// where('price', '>=', 1000)             // 比較演算子つき

引数(表)

引数必須既定値説明
$keystring|intはい取得キー。user.age のようなドット記法可
$operatorOrValuemixedはい値 または 演算子(>, >=, <, <=, !=, = など)
$valuemixedいいえnull演算子を使う場合の比較値
  • 戻り値static(呼び出し元と同種の Collection / LazyCollection)
  • 例外/副作用:例外なし。元コレクションは不変(非破壊)

使用例

最小例

<?php

use Illuminate\Support\Collection;

$users = collect([
    ['id' => 1, 'name' => 'Aoi',  'active' => true ],
    ['id' => 2, 'name' => 'Bea',  'active' => false],
    ['id' => 3, 'name' => 'Chin', 'active' => true ],
]);

$active = $users->where('active', true);

// キーは保持される(0,1,2のまま true の行だけ)
$reindexed = $active->values(); // [0 => ..., 1 => ...]

実務例(Eloquent結果の後処理)

<?php

use App\Models\User;

// 例: すでにDBから取得済み(N件)をさらに後段で絞る
$users = User::with('profile')->get();

$target = $users
    ->where('role', 'admin')                 // '='(ゆるい比較)
    ->where('verified', true)                // 真偽値で合致
    ->where('profile.age', '>=', 30)         // ドット記法でネストを参照
    ->values()                               // 並び直したいときは再採番
    ->pluck('email');                        // 必要な列だけに

よくある落とし穴・注意

  • 比較は既定でゆるい(=='0'0 が等しいなど型変換が起こる。厳密比較が必要なら whereStrict を使う。
  • キー保持where は元のキーを維持。0始まりで再採番したい場合は values() を併用。
  • 巨大データO(n) なので大量件数はDBやクエリビルダでの where で先に絞るほうが効率的。
  • 引数並び:2引数なら = 判定(where('id', 5))。比較演算子を使うときは3引数(where('price', '>=', 1000))。

代替・関連APIとの比較

  • whereStrict($key, $value)=== の厳密比較。型差異で弾きたい場合はこちら。
  • filter(callable):任意ロジックで絞る柔軟版。複合条件や計算を含む場合に有効。
  • firstWhere($key, $operatorOrValue, $value = null):最初の一致要素だけ取得。where(...)->first() より短く可読。
  • whereIn($key, array $values) / whereBetween($key, array $range):複数候補/範囲での絞り込みに特化。

collection固有メモ

  • チェーン可否:可(where()->where()->pluck() など)
  • 破壊的/非破壊非破壊(新インスタンス返却)
  • キー保持保持(必要なら values()
  • LazyCollection:対応(遅延評価で必要分のみ処理)
  • 計算量O(n)(条件評価は各要素1回)

入出力対応ミニ表

入力呼び出し出力(概念)
[{id:1},{id:2},{id:3}]where('id', '>=', 2)[{id:2},{id:3}](キー保持)
[{ok:'1'},{ok:1}]where('ok', 1)両方一致(ゆるい比較)
同上whereStrict('ok', 1)後者のみ(厳密比較)

テスト例(Pest)

<?php

use Illuminate\Support\Collection;

it('filters by key and keeps keys', function () {
    $c = collect([
        10 => ['x' => 1],
        20 => ['x' => 2],
        30 => ['x' => 1],
    ]);

    $r = $c->where('x', 1);

    expect($r->keys()->all())->toBe([10, 30]); // キー保持
    expect($r->values()->count())->toBe(2);    // values() で再採番可能
});

it('uses loose comparison by default', function () {
    $c = collect([['ok' => '0'], ['ok' => 0]]);
    expect($c->where('ok', 0)->count())->toBe(2); // '0' も一致
});

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

症状/エラー原因対処
期待より件数が多い/少ないゆるい比較で型が吸収されている厳密にしたい場合は whereStrict、または値の型整形
並び順や連番が崩れたキー保持の影響values() で再採番、sortBy() でソート
ネストキーでヒットしないキーパスの指定ミスuser.profile.age のように正しいドット記法に修正
パフォーマンスが悪い大量データをアプリ側で絞っているクエリ段階で where、必要最小限だけ取得

参考リンク

レン (Wren)

こんにちは。レンです。

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

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

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

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

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

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