- カテゴリ: collection
- 掲載バージョン: Laravel 12・PHP 8.4
- 名前空間 / FQCN / コマンド:
Illuminate\Support\Collection::only - 関連: except / pluck / keys / Arr::only / intersectByKeys
- 変更履歴: —
要点(TL;DR)
- 連想配列コレクションから指定したキーだけを残した部分集合を返す
- 例:
collect($user)->only(['id', 'name']) - 罠:ネストには効かない/値の抽出は
pluck/数値キーは再インデックスされない
概要
only はコレクションのトップレベルのキーでフィルタし、指定キーだけを保持した新しいコレクションを返します。データのホワイトリスト化や、レスポンスから不要フィールドを落とす用途に適します。only は Enumerable が提供するメソッドのため、通常の Collection だけでなく LazyCollection でも利用できます。(Laravel API)
構文 / シグネチャ
public function only(array|string $keys): static
- 引数(表)
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
$keys | `array | string` | ✔ | — |
- 戻り値:
Collection/LazyCollection(同じ型の新インスタンス) - 例外/副作用:なし(非破壊・純粋関数)
コレクション特性(カテゴリ追加情報)
- チェーン可否:可(
staticを返す) - 破壊的/非破壊:非破壊(元のコレクションは変更されない)
- キー保持:保持(元のキーと順序を維持)
- LazyCollection:対応(
Enumerable実装)(Laravel API) - 計算量:概ね O(n)(内部的にキーの集合で照合)
- 備考:実装は配列ヘルパ
Arr::only相当の挙動(指定キーとのキー積集合)。(Laravel API, PHP)
使用例
最小例
<?php
use Illuminate\Support\Collection;
$user = collect([
'id' => 10,
'name' => 'Alice',
'email' => 'alice@example.com',
'is_admin' => false,
]);
$public = $user->only(['id', 'name']);
// ['id' => 10, 'name' => 'Alice']
実務例:Eloquent結果を主キーで絞る(keyBy 併用)
<?php
use App\Models\User;
// ユーザー一覧を id をキーにしたコレクションへ
$users = User::query()->get()->keyBy('id');
// 通知対象IDだけ抽出
$targetIds = [3, 7, 9];
$targets = $users->only($targetIds);
// $targets は id 3,7,9 のモデルだけを保持(他は落ちる)
実務例:APIレスポンスのホワイトリスト
<?php
use Illuminate\Support\Arr;
$payload = collect([
'id' => 501,
'title' => 'Sample',
'body' => '...',
'tags' => ['laravel', 'collection'],
'debug' => ['trace' => '...'],
]);
// 公開したいキーだけ
return $payload->only(['id', 'title', 'tags'])->all();
よくある落とし穴・注意
- ネスト非対応:
onlyはトップレベルキーのみ対象。ネストを絞るならmap(fn ($row) => collect($row)->only([...]))など行ごとに処理、配列ならArr::onlyを活用。(Laravel) - 値の抽出ではない:値(カラム)リストが欲しいときは
pluck。only(['name'])は['name' => '...']を返し、pluck('name')は['...']を返す。 - 数値キーは再インデックスされない:
only([2, 5])の結果キーは2,5のまま。連番にしたければ->values()を後置。 - 存在しないキーは無視:指定しても入らない(例外なし)。
代替・関連APIとの比較
except([...]):指定キー以外を残す(ブラックリスト)。pluck('field'):値の抽出(ネスト対応・ドット記法可)、形が配列になる点が異なる。intersectByKeys($items):他コレクションのキーとの積集合で絞るときに有効。Arr::only($array, [...]):生配列を処理したい場合に。onlyと同等のキー選抜を配列で実行。(Laravel API)
入出力対応表(小さなサンプル)
| 入力 | 呼び出し | 出力 |
|---|---|---|
collect(['a'=>1,'b'=>2,'c'=>3]) | ->only(['a','c']) | ['a'=>1,'c'=>3] |
collect([10,20,30,40]) | ->only([0,3]) | [0=>10,3=>40] |
collect([['id'=>1,'n'=>'A'],['id'=>2,'n'=>'B']]) | ->only([1]) | [1=>['id'=>2,'n'=>'B']] |
User::all()->keyBy('id') | ->only([5,9]) | id=5,9 の User モデルのみ |
テスト例(Pest)
<?php
use Illuminate\Support\Collection;
it('keeps only specified keys without reindexing', function () {
$c = collect(['a' => 1, 'b' => 2, 'c' => 3]);
expect($c->only(['c', 'a'])->all())->toBe(['a' => 1, 'c' => 3]);
expect(array_keys($c->only(['b'])->all()))->toBe(['b']);
});
it('ignores missing keys', function () {
$c = collect(['x' => 1]);
expect($c->only(['x', 'y'])->all())->toBe(['x' => 1]);
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
| 期待の値配列にならない | only は値抽出ではなくキー選抜 | 値が欲しいなら pluck を使用 |
結果キーが 0,1,2... でない | 数値キーは保持される | ->values() を併用して再インデックス |
| ネスト下のキーが残らない | only はトップレベルのみ | 行ごとに collect($row)->only([...])、または Arr::only を併用 |
| Eloquent コレクションで思ったIDが取れない | コレクションがidでキー付けされていない | ->keyBy('id') してから only([..]) |

