- カテゴリ: collection
- 掲載バージョン: Laravel 12・PHP 8.4
- 名前空間 / FQCN / コマンド:
Illuminate\Support\Collection::whereIn - 関連: where / whereStrict / whereInStrict / whereNotIn / filter
- 変更履歴: ―
要点(TL;DR)
- 配列(候補値)のいずれかに一致する要素だけを非破壊で絞り込み
- 最低限の使い方:
$users->whereIn('status', ['active','pending']); - 罠
- 比較は緩やか(==)。厳密比較は
whereInStrict - キーは保持される(必要なら
values()で振り直し) - クエリビルダの
whereInと異なりメモリ上で実行(大量件数は注意)
- 比較は緩やか(==)。厳密比較は
概要
コレクション中の各要素から指定キーの値を取り出し、その値が与えた配列に含まれるものだけを残します。where が「単一値との等価」を見るのに対し、whereIn は「複数候補のいずれか」を手早く表現できます。Eloquent 取得後の軽い絞り込みや、API レスポンスの後処理に有用です。
構文 / シグネチャ
Collection whereIn(string|int $key, array $values);
- 引数
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
| $key | string|int | ✅ | — | 取り出すキー。dot 記法でネスト可(例: user.role) |
| $values | array | ✅ | — | 許可する値の配列 |
- 戻り値:
Illuminate\Support\Collection(元コレクションを変更しない新インスタンス) - 例外/副作用:例外なし。内部で
data_get()によりプロパティ/配列アクセス
カテゴリ別の要点(collection)
- チェーン可否: 可
- 破壊的/非破壊: 非破壊
- キー保持: 保持(必要なら
values()) - LazyCollection: 対応(遅延評価で O(n) 逐次)
- 計算量の目安: O(n)(
in_array相当)
入出力対応(小さなサンプル)
| 入力要素 | values | 出力(キー保持) |
|---|---|---|
['id'=>10,'status'=>'active'] | ['active','pending'] | 残る |
['id'=>11,'status'=>'disabled'] | ['active','pending'] | 除外 |
['id'=>12,'status'=>'pending'] | ['active','pending'] | 残る |
使用例
最小例
<?php
use Illuminate\Support\Collection;
$users = collect([
['id' => 1, 'name' => 'A', 'status' => 'active'],
['id' => 2, 'name' => 'B', 'status' => 'disabled'],
['id' => 3, 'name' => 'C', 'status' => 'pending'],
]);
$visible = $users->whereIn('status', ['active', 'pending']);
// 結果: id 1 と 3(キー 0,2 を保持)
実務例(ネスト・キー振り直し・厳密比較)
<?php
use Illuminate\Support\Collection;
// 受注データを API から取得した配列と仮定
$orders = collect([
['no' => 'A001', 'customer' => ['country' => 'JP'], 'total' => 5000],
['no' => 'A002', 'customer' => ['country' => 'US'], 'total' => 12000],
['no' => 'A003', 'customer' => ['country' => 'FR'], 'total' => 8000],
]);
// 対象国の受注のみ
$target = $orders
->whereIn('customer.country', ['JP', 'US']) // dot 記法でネスト抽出
->values(); // 連番キーに振り直し
// 厳密比較が必要なとき(例:'0' と 0 を区別)
$strict = $orders->whereInStrict('customer.country', ['JP']);
大量データの注意(DB側でやるべきケース)
<?php
use App\Models\User;
// 悪手:全件を取得してからメモリで絞る
$ng = User::all()->whereIn('status', ['active','pending']);
// 推奨:SQL の whereIn で絞り込み(DB最適化の恩恵を受ける)
$ok = User::query()->whereIn('status', ['active','pending'])->get();
よくある落とし穴・注意
- 緩やかな等価:
whereInは緩やか比較(==)相当。型を区別したい場合はwhereInStrict。 - キー保持:フィルタ後も元のキーが残る。連番配列が必要なら
values()。 - スカラ配列には不向き:要素自体がスカラ値のコレクションでは
$keyが取れない。filter(fn($v)=>in_array($v,$values,true))を使用。 - パフォーマンス:大量件数は DB 側
whereInを優先。コレクション版は取得後の後処理向け。 - null マッチ:
$valuesにnullを含めると、キー未定義/値がnullの要素もヒットし得る。明示的に避けたい場合は事前に除外。
代替・関連APIとの比較
where:単一値との等価。候補が複数ならwhereInが簡潔。whereInStrict:型まで一致必須(===)。ID・フラグの厳密比較に。whereNotIn/whereNotInStrict:逆条件(候補に含まれないもの)。filter:自由条件。複合ロジックや範囲条件に有利。- クエリビルダ
whereIn:DB で実行。大量件数ではこちらを使う。
テスト例(Pest)
<?php
use Illuminate\Support\Collection;
it('filters by whereIn and keeps keys', function () {
$items = collect([
10 => ['role' => 'admin'],
11 => ['role' => 'user'],
12 => ['role' => 'guest'],
]);
$filtered = $items->whereIn('role', ['admin', 'user']);
expect($filtered->keys()->all())->toBe([10, 11])
->and($filtered->pluck('role')->all())->toBe(['admin', 'user']);
});
it('uses strict comparison when requested', function () {
$items = collect([
['flag' => 0],
['flag' => '0'],
['flag' => 1],
]);
$loose = $items->whereIn('flag', ['0']); // 0 と '0' が一致しがち
$strict = $items->whereInStrict('flag', ['0']); // '0' のみ
expect($loose)->toHaveCount(2)
->and($strict)->toHaveCount(1);
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
| 結果が空になる | $key の綴り/ネストが誤り | data_get($item, 'customer.country') でデバッグし実在確認 |
| 期待より多くヒットする | 緩やか比較により ‘0’ と 0 などが一致 | whereInStrict を使用 |
| 並び順が崩れた | キー保持により想定外の順序で扱っている | values()->sortBy(...) などで整形 |
| JSON 文字列を比較して一致しない | 値が JSON 文字列・配列で型不一致 | 事前に型変換し、whereInStrict を使う |
参考リンク
- Laravel公式「Collections: whereIn」:https://laravel.com/docs/12.x/collections#method-wherein
- Laravel公式「Collections: whereInStrict」:https://laravel.com/docs/12.x/collections#method-whereinstrict
- Laravel公式「Helpers: data_get」:https://laravel.com/docs/12.x/helpers#method-data-get
- Laravel公式「Lazy Collections」:https://laravel.com/docs/12.x/collections#lazy-collections
- PHP公式「in_array」:https://www.php.net/in_array
