- カテゴリ: 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) // 比較演算子つき
引数(表)
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
| $key | string|int | はい | — | 取得キー。user.age のようなドット記法可 |
| $operatorOrValue | mixed | はい | — | 値 または 演算子(>, >=, <, <=, !=, = など) |
| $value | mixed | いいえ | 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、必要最小限だけ取得 |
参考リンク
- Laravel Docs — Collections: where
https://laravel.com/docs/12.x/collections#method-where - Laravel Docs — Collections: whereStrict / firstWhere / whereIn / whereBetween / filter
https://laravel.com/docs/12.x/collections - Laravel Docs — Helpers: data_get(ドット記法アクセス)
https://laravel.com/docs/12.x/helpers#method-data-get

