- カテゴリ: collection
- 掲載バージョン: Laravel 12・PHP 8.4
- 名前空間 / FQCN / コマンド:
Illuminate\Support\Collection::pluck - 関連: mapWithKeys, keyBy, values, data_get, Eloquent Builder::pluck
- 変更履歴: Laravel 12.x(12.20.0系):
$value/$keyにClosureを渡せるように拡張 (Laravel News)
要点(TL;DR)
- 配列/モデル配列の「特定カラム(キー)」だけを抜き出して 新しいCollection を作る
- 最低限の使い方:
$names = $users->pluck('name'); - よくある罠
概要
pluck は、コレクション各要素(配列/オブジェクト)から、指定したキーの値だけを抽出して新しいコレクションを作ります。フォームの選択肢(id => name)や、ログ/DTOの一部フィールドだけ欲しい時に最短で書けます。ネストはドット記法にも対応します。 (Laravel)
「Laravel pluck」で調べる場合、多くは Illuminate\Support\Collection::pluck() ではなく Eloquentモデル / クエリビルダの pluck()(DBから直接1〜2カラムだけ取り出すメソッド)を探しています。両者はメソッド名も引数も同じですが、動く場所とSQLへの影響が異なるため、この記事では両方を扱います。
構文 / シグネチャ
use Illuminate\Support\Collection;
/**
* @param string|array|\Closure $value // 取得する値(キー or ネスト指定 or 変換Closure)
* @param string|array|\Closure|null $key // 結果のキー(任意)
* @return \Illuminate\Support\Collection
*/
$plucked = $collection->pluck($value, $key = null);
- 引数
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
$value | string | array(Laravel 12.xで Closure も可) | ✅ | – | 取り出す値のキー。ネストはドット記法(例: a.b) (Laravel) |
$key | string | array | null(Laravel 12.xで Closure も可) | ❌ | null | 結果コレクションのキーに使う値のキー(重複時は後勝ち) (Laravel) |
- 戻り値:
Collection(抽出結果の新しいコレクション) - 例外/副作用:基本なし(元コレクションは変更しない/非破壊)
使用例
最小例
use Illuminate\Support\Collection;
$collection = collect([
['product_id' => 'prod-100', 'name' => 'Desk'],
['product_id' => 'prod-200', 'name' => 'Chair'],
]);
$names = $collection->pluck('name');
dump($names->all()); // ['Desk', 'Chair']
(公式例と同等) (Laravel)
実務例(select用の id => label を作る)
use App\Models\User;
$items = User::query()
->where('active', true)
->get(['id', 'name']) // ここは明示しておくと意図が伝わりやすい
->pluck('name', 'id'); // [id => name] の Collection
// Bladeなら: @foreach($items as $id => $name) ...
もし「結果を配列で欲しい」なら
->all()、連番キーにしたいなら->values()を併用します。
Eloquent(クエリビルダ)の pluck — DBから直接抽出する
Eloquentモデルやクエリビルダにも同名の pluck() があります。こちらは get() で全カラムを取得してから絞り込むのではなく、SELECT文の段階で指定カラムだけを取得するため、レコード数が多いテーブルほどDB負荷とメモリ消費を抑えられます。
use App\Models\User;
// SELECT `name` FROM `users` 相当(全カラムを取得しない)
$names = User::pluck('name');
// SELECT `id`, `email` FROM `users` 相当。[id => email] の連想配列
$emails = User::pluck('email', 'id');
フォームの選択肢を作る(Bladeで <select> を組み立てる例)
// Controller側
$users = User::pluck('name', 'id'); // [id => name]
// Blade側
<select name="user_id">
@foreach ($users as $id => $name)
<option value="{{ $id }}">{{ $name }}</option>
@endforeach
</select>
- 大量データを扱う場合:
pluck()も結果は一括でメモリに載るため、件数が非常に多いテーブルではwhere()で絞り込むか、chunk やクエリビルダのlazy()/cursor()との併用を検討します。 - N+1問題との違い:
pluck()はリレーション先の一覧取得(例: 全ユーザーのメールアドレス一覧)には有効ですが、$user->posts->pluck('title')のようにループ内でリレーションを都度読みに行くとN+1問題は別途発生します。事前にwith()で eager loading しておく点は他のリレーション取得と同じです。
よくある落とし穴・注意
- キー重複は後勝ち:
pluck('color', 'brand')のように$keyを指定して重複すると最後の要素で上書きされます。 (Laravel) - ネストはドット記法:配列の深い場所を
speakers.first_dayのように取れます(data_get相当の挙動を期待すると安全)。 (Laravel) - 計算量の目安:O(n)(要素を1回走査)
- チェーン可否 / 破壊的:チェーン可、非破壊(新しいCollectionを返す)
- LazyCollection:
LazyCollection側にもpluck関連の実装があり、同様の抽出用途で使えます(大量データならlazy()/cursor()と組み合わせる選択肢)。 (api.laravel.com)
代替・関連APIとの比較
keyBy():要素全体をキーで引き直したい(id => モデル/配列)ならこちら。mapWithKeys():キーと値を自由に整形して['k' => 'v']を作りたい(複雑な加工)ならこちら。- values():
pluck()後に連番に振り直したい時(キー指定した/元キーが残った等)。 - only():キーの値ではなく、複数カラムを保ったまま要素を絞りたいならこちら。
- groupBy():値ごとに1件だけ残す(後勝ち)ではなく、同じキーの要素を配列としてまとめたいならこちら。
- combine():すでに分かれているキー配列と値配列を組み合わせたいなら、
pluck()よりcombine()が直接的。 - Eloquentの
pluck()(Builder):DBから1〜2カラムだけ取る用途なら クエリ側のpluckが高速・省メモリになりやすい(必要カラムのみ取得)。Eloquentの基本も参照。
テスト例(Pest)
it('can pluck values and key them', function () {
$collection = collect([
['id' => 10, 'name' => 'Desk'],
['id' => 20, 'name' => 'Chair'],
]);
expect($collection->pluck('name')->all())->toBe(['Desk', 'Chair']);
expect($collection->pluck('name', 'id')->all())->toBe([10 => 'Desk', 20 => 'Chair']);
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
pluck したら null だらけ | 指定キーが存在しない / ネスト指定が間違い | キー名を確認。ネストはドット記法にする。必要なら filter() で除去 |
$key 指定したら件数が減った | キー重複で上書き(後勝ち) (Laravel) | キーがユニークになるよう見直す or groupBy() 等へ設計変更 |
| 取りたいのが「2列」以上 | pluck は基本1列(+キー列) | map->only([...]) / select / DTO化などに切り替える |
参考リンク
- Laravel 12.x Collections —
pluck()(Laravel) - Laravel News — pluckがClosure対応(2025-09-22) (Laravel News)
- LaravelVersions(12.x変更一覧に pluck Closure 対応が記載) (Laravel Versions)
