only — 指定キーだけを抜き出す

collection
  • カテゴリ: 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 はコレクションのトップレベルのキーでフィルタし、指定キーだけを保持した新しいコレクションを返します。データのホワイトリスト化や、レスポンスから不要フィールドを落とす用途に適します。onlyEnumerable が提供するメソッドのため、通常の Collection だけでなく LazyCollection でも利用できます。(Laravel API)

構文 / シグネチャ

public function only(array|string $keys): static
  • 引数(表)
引数必須既定値説明
$keys`arraystring`
  • 戻り値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)
  • 値の抽出ではない:値(カラム)リストが欲しいときは pluckonly(['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([..])

参考リンク

レン (Wren)

こんにちは。レンです。

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

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

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

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

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

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