Collection::only

Returns a new collection containing just the items whose keys are in the given list.

Signature
public function only(\Illuminate\Support\Enumerable|array|string|null $keys): static

Parameters

ParameterTypeDescription
$$keys\Illuminate\Support\Enumerable|array|string|nullThe keys to keep. An array, another enumerable, a single key, or several keys as separate arguments. Passing null returns every item.

Return value

Illuminate\Support\CollectionA new collection holding only the requested keys, in the original collection's order.

only narrows a collection to a named set of keys. It is implemented with array_intersect_key, which explains both its speed and its two quirks: keys you ask for that do not exist are simply absent from the result, and the surviving items keep the original collection's order rather than the order you listed the keys in.

When to reach for it

Whitelisting. Reducing a request payload to the fields a model is allowed to accept, trimming a model's array form before it goes into a response or a log line, or narrowing a config array to the options a component understands. except is the inverse and is the wrong default for untrusted input — a whitelist fails closed when a new field appears, a blacklist does not.

What trips people up

It works on keys, never on values, so it is useless on a plain list of rows unless you are selecting by numeric position. To keep only certain columns from every row, map only over the rows. Missing keys are silent, which means a typo produces a quietly incomplete result rather than an error. And on an Eloquent collection the behaviour differs — there it selects models by primary key.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Whitelist the fields of an incoming payload before passing them to a model.
  • Trim a record down to a handful of columns before writing it to a log.
  • Narrow a config array to the options a component actually reads.

Frequently asked questions

What happens if I ask for a key that does not exist?

It is skipped silently and the result simply lacks that key — no error and no null placeholder. Compare the result's count against your key list if a missing field should be an error.

Does the result follow the order of the keys I passed?

No. It preserves the collection's own ordering, because the filtering is done with array_intersect_key.

How do I keep only certain columns from a collection of rows?

Map over the rows and apply the method to each one; called on the outer collection it would select rows by their numeric index instead.

More examples

Selecting columns from every row

The method acts on the keys of one collection, so hiding the 'cost' column from a list of rows means mapping it over each row. The output keeps two rows, each with only id, name and price.

Example · php
<?php

$rows = collect([
    ['id' => 1, 'name' => 'Desk', 'cost' => 40, 'price' => 100],
    ['id' => 2, 'name' => 'Chair', 'cost' => 20, 'price' => 50],
]);

$public = $rows->map(fn (array $row) => collect($row)->only(['id', 'name', 'price'])->all());

print_r($public->all());

only versus except

Both calls produce the same result today. They diverge the moment a new field arrives in the input: the whitelist keeps ignoring it, while the blacklist lets it straight through, which is why only() is the safer choice for untrusted data.

Example · php
<?php

$input = collect([
    'title' => 'Hello',
    'body' => 'World',
    'is_admin' => true,
]);

print_r($input->only(['title', 'body'])->all());
print_r($input->except(['is_admin'])->all());

Trimming a model for a log line

Keeps the log line small and avoids writing sensitive attributes. This needs a booted application with the Log facade resolved, so it is shown rather than executed.

Example · php
<?php

Log::info('order.updated', collect($order->getAttributes())
    ->only(['id', 'status', 'total'])
    ->all());

Discussion

  • Be the first to comment on this lesson.