- カテゴリ: collection
- 掲載バージョン: Laravel 12・PHP 8.4
- 名前空間 / FQCN / コマンド:
Illuminate\Support\Collection::search - 関連: contains / first / firstWhere / where / filter
- 変更履歴: —
要点(TL;DR)
- コレクション内から値または条件に一致する最初の要素のキーを返す
- 使い方:
$key = collect([10, 20])->search(20); // 1 - よくある罠
- 見つからない時は
falseを返すため、if ($key !== false)で判定する(キー0と区別) - 厳密比較は
$strict = trueを指定('2'と2を区別) - ネストした配列/オブジェクトはコールバックで評価する
- 見つからない時は
概要
searchはコレクションから値を検索し、最初に一致した要素のキー(int|string)を返します。値一致のほか、コールバックで任意の条件検索が可能です。該当がなければfalse。重複がある場合は最初の一致のみが対象です。
構文 / シグネチャ
public function search(mixed $value, bool $strict = false): int|string|false;
- 引数
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
$value | mixed または `callable(mixed $item, int | string $key): bool` | ✓ | — |
$strict | bool | false | trueで===の厳密比較。falseは== |
- 戻り値:
int|string|false— 一致した要素のキー。見つからなければfalse - 例外/副作用:なし
カテゴリ別追記(Collection)
- チェーン可否:不可(スカラーを返すためチェーン終了)
- 破壊的/非破壊:非破壊
- キー保持:元のキーをそのまま返す
- LazyCollection:対応(見つかり次第早期終了)
- 計算量:平均 O(n)(先頭一致で短縮あり)
入出力対応ミニサンプル
| 入力 | 呼び出し | 出力 |
|---|---|---|
[10, 20, 30] | search(20) | 1 |
['a' => 1, 'b' => 2] | search(2) | 'b' |
['2', 2] | search('2', true) | 0 |
[['id'=>1], ['id'=>2]] | search(fn($x)=>$x['id']===2) | 1 |
[10] | search(9) | false |
使用例
最小例
<?php
use Illuminate\Support\Collection;
$numbers = collect([2, 4, 6, 8]);
$key = $numbers->search(6); // 2
$strictFail = $numbers->search('6', true); // false(型が違うため)
// 見つからない= false。キー0と区別して判定
if ($key !== false) {
echo "found at key: {$key}\n";
}
実務例:配列DTOからメール一致ユーザーのキーを取得
<?php
use Illuminate\Support\Collection;
$users = collect([
['id' => 10, 'email' => 'alice@example.com'],
['id' => 11, 'email' => 'bob@example.com'],
['id' => 12, 'email' => 'carol@example.com'],
]);
$target = 'bob@example.com';
$key = $users->search(fn ($u) => $u['email'] === $target);
if ($key === false) {
// ログや例外などの分岐
throw new RuntimeException('User not found.');
}
$user = $users[$key]; // ['id'=>11, ...]
よくある落とし穴・注意
0キー問題:if ($key)で判定すると、キー0が偽と評価される。**$key !== false**で判定。- 厳密比較:数値と文字列が混在する場合は
$strict=trueを使うか、コールバックで明示比較。 - ネスト/オブジェクト:単純値比較は意図通りにならないことがある。コールバックでフィールド比較を使う。
- 重複値:最初の一致のみ。すべて欲しい場合は
filter()→keys()を使う。
代替・関連APIとの比較
contains($value|callable):**存在の有無(bool)**だけ欲しいとき。キーは不要。first($callback)/firstWhere($key, $op?, $value?):要素本体が欲しいとき。where()/filter():複数一致を抽出したいとき。- 選定基準:キーが必要→
search、要素が必要→first/firstWhere、存在だけ→contains、複数抽出→filter/where。
テスト例(Pest)
<?php
use Illuminate\Support\Collection;
it('returns first matching key', function () {
$c = collect(['a' => 1, 'b' => 2, 'c' => 2]);
expect($c->search(2))->toBe('b'); // 最初の一致
});
it('distinguishes 0 key from false', function () {
$c = collect([99]);
$key = $c->search(99);
expect($key)->toBe(0);
expect($key !== false)->toBeTrue();
});
it('supports callback condition', function () {
$c = collect([[ 'id' => 1 ], [ 'id' => 3 ]]);
$key = $c->search(fn ($x) => $x['id'] > 1);
expect($key)->toBe(1);
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
期待していたがfalseになる | 型が異なる('2' vs 2) | $strict=trueを指定、またはコールバックで===比較 |
if ($key)が通らない | 一致キーが0 | if ($key !== false)で判定 |
| ネスト配列で一致しない | 値比較が配列同士になっている | search(fn($x) => $x['field'] === 'value')のようにコールバックで比較 |
| 2件目以降の一致が欲しい | searchは最初の一致のみ | filter(...)->keys()で全キー取得 |
参考リンク
- Laravel 公式ドキュメント:Collections — search(Laravel 12)
https://laravel.com/docs/12.x/collections#method-search - ソースコード(
Illuminate\Support\Collection)
https://github.com/laravel/framework/blob/12.x/src/Illuminate/Support/Collection.php - 関連:
contains/firstWhere/filter
https://laravel.com/docs/12.x/collections#method-contains
https://laravel.com/docs/12.x/collections#method-firstWhere
https://laravel.com/docs/12.x/collections#method-filter

