Arr::pluck
Extracts one field from every row of an array, optionally keying the result by another field.
public static function pluck($array, $value, $key = null)Parameters
| Parameter | Type | Description |
|---|---|---|
$$array | iterable | The rows to pluck from. Any iterable works, including a Generator. |
$$value | string|array|int|Closure|null | Dot path to the value, an already-exploded path array, or a Closure receiving the whole item. null returns the item itself. |
$$keyoptional | string|array|Closure|null= null | Dot path or Closure producing the key for each result entry. When null the result is a plain list. |
Return value
arrayAn array of the extracted values, either as a list or keyed by the resolved key field.
Arr::pluck is array_column with dot paths, object support and a Closure escape hatch. Each row is resolved through data_get, so 'developer.name' reaches into nested arrays and into public properties or ArrayAccess objects alike.
When to reach for it
- Turning a list of records into a flat list of ids for a
whereInor animplode. - Building an
id => labelarray for a select box in one call. - Reading a nested field, such as
'meta.tracking.utm_source', out of a decoded JSON payload.
What trips people up
Supplying $key makes the result a map, and duplicate keys overwrite. If two rows share the key value, only the last survives — a silently shorter array.
A missing path yields null, not a skipped row. The result always has one entry per input row (before key collisions), so a typo in the path produces an array of nulls rather than an error. Chain Arr::whereNotNull if that matters.
The key is cast to an array key. Objects are only usable as keys when they define __toString; numeric strings become integers.
A * segment in the path makes data_get collect matches, so a value like 'items.*.sku' returns a nested array per row, not a flat one.
Example
When to use it
- Collect the ids from a list of rows to feed a whereIn query.
- Build an id => name array for a dropdown in a single call.
- Read a nested field out of every item in a decoded JSON payload.
Frequently asked questions
What is the difference between Arr::pluck and array_column?
Arr::pluck supports dot notation for nested values, accepts objects and Closures, and works on any iterable, whereas array_column handles only a single flat column on arrays and objects with public properties.
Why does my plucked array contain null values?
Because a row did not have the requested path — pluck emits one entry per row regardless. Wrap the result in Arr::whereNotNull, then array_values, to remove them.
How do I key the result by a column?
Pass the key's dot path as the third argument, as in Arr::pluck($rows, 'name', 'id'). Make sure that column is unique, since duplicates overwrite each other.
More examples
Missing paths become null, and Closures compute values
The first output has three entries including a null for the row without meta. The second shows the whereNotNull cleanup. The third shows that both the value and the key arguments accept Closures, so derived values need no separate map step.
<?php
use Illuminate\Support\Arr;
$rows = [
['id' => 1, 'name' => 'Desk', 'meta' => ['sku' => 'D-1']],
['id' => 2, 'name' => 'Chair'],
['id' => 3, 'name' => 'Lamp', 'meta' => ['sku' => 'L-9']],
];
// Row 2 has no meta.sku, so it contributes null rather than being skipped.
print_r(Arr::pluck($rows, 'meta.sku'));
// Drop the holes.
print_r(array_values(Arr::whereNotNull(Arr::pluck($rows, 'meta.sku'))));
// A Closure receives the whole row.
print_r(Arr::pluck($rows, fn (array $row) => strtoupper($row['name']), 'id'));
/*
Array
(
[0] => D-1
[1] =>
[2] => L-9
)
Array
(
[0] => D-1
[1] => L-9
)
Array
(
[1] => DESK
[2] => CHAIR
[3] => LAMP
)
*/Plucking from Eloquent results
Because resolution goes through data_get, the same dot syntax that works on nested arrays also traverses model attributes and loaded relations. Passing null as the value argument keys the untouched records, which is a compact alternative to Arr::mapWithKeys.
<?php
use App\Models\User;
use Illuminate\Support\Arr;
$users = User::with('team')->get()->all(); // plain array of models
// data_get reads model attributes and relations, so dot paths work on objects.
$teamNames = Arr::pluck($users, 'team.name', 'id');
// [1 => 'Platform', 2 => 'Growth', ...]
// Passing null as the value keys the whole records by a field.
$byEmail = Arr::pluck($users, null, 'email');
// ['[email protected]' => User { ... }, ...]
Discussion