Collection::first
Returns the first item in a collection, optionally the first one passing a truth test.
Collection::first(?callable $callback = null, mixed $default = null): TValue|TFirstDefaultParameters
| Parameter | Type | Description |
|---|---|---|
$callbackoptional | (callable(TValue, TKey): bool)|null= null | Truth test invoked with the item value first and its key second. Omit it to take the very first item regardless of content. |
$defaultoptional | TFirstDefault|(\Closure(): TFirstDefault)= null | Value returned when nothing matches. If a closure is given it is invoked lazily, only in the no-match case. |
Return value
TValue|TFirstDefaultThe first item in the collection, or the first item for which the callback returned true. When the collection is empty or nothing passes the test, the default is returned instead — resolved by calling it if it is a closure.
first is the collection equivalent of taking the head of a list, with an optional predicate. Called bare it hands back element zero; called with a callback it scans in order and returns the first item that passes, stopping as soon as it finds one.
When to reach for it
Use it when you want one item out of data you already have, and when "nothing matched" is a normal outcome rather than an error. It is the natural partner to filter when you only ever needed a single row — first short-circuits, whereas filter()->first() tests every element before discarding all but one.
The thing that trips people up
An empty collection and a collection whose first element is null both return null, so a bare null check cannot tell "no rows" from "a row containing nothing". Use isEmpty() when that distinction matters, or pass a sentinel default.
The second argument is a genuine default, not a fallback that runs unconditionally. When it is a closure it is resolved through value(), so an expensive fallback costs nothing on the happy path. That laziness is one-way, though — passing expensiveCall() rather than fn () => expensiveCall() evaluates it every time.
When a missing item really is a bug, firstOrFail has the same signature but throws Illuminate\Support\ItemNotFoundException instead of returning a default.
Example
When to use it
- Grab the single most recent record out of an already-loaded relation without another query.
- Find the first configuration entry matching a condition, falling back to a computed default.
- Short-circuit a scan over a large in-memory list as soon as one match is found.
Frequently asked questions
What does first() return when the collection is empty?
It returns null, or the second argument if you supplied one. Because a collection whose first item is null returns null too, use isEmpty() when you need to distinguish an empty collection from a null value.
Is the default argument to first() evaluated even when a match is found?
Only if you pass a plain value. A closure default is resolved through value() and is invoked exclusively in the no-match case, so wrap anything expensive in fn () => ... to keep it off the happy path.
How do I make first() throw instead of returning null?
Use firstOrFail(), which accepts the same optional truth test and raises Illuminate\Support\ItemNotFoundException when nothing matches or the collection is empty.
More examples
firstOrFail throws instead of returning a default
Both blocks print Illuminate\Support\ItemNotFoundException. firstOrFail takes the same optional truth test as first, but has no default parameter — the absence of a match is treated as an error. Reach for it in service code where a missing item means a broken invariant, and let the exception handler turn it into a 404.
<?php
use Illuminate\Support\ItemNotFoundException;
try {
collect([1, 2, 3])->firstOrFail(fn (int $v) => $v > 5);
} catch (ItemNotFoundException $e) {
echo get_class($e), PHP_EOL;
}
try {
collect([])->firstOrFail();
} catch (ItemNotFoundException $e) {
echo 'empty: ', get_class($e), PHP_EOL;
}first versus filter then first
Both lines produce the value 4, but the counters differ sharply: first stops at the fourth element, while filter evaluates all one thousand before first takes the head. On small collections the difference is irrelevant; on large ones, or when the callback does real work, reach for first directly.
<?php
$checked = 0;
$values = collect(range(1, 1000));
$a = $values->first(function (int $v) use (&$checked) {
$checked++;
return $v > 3;
});
echo $a, ' after ', $checked, ' tests', PHP_EOL;
$checked = 0;
$b = $values->filter(function (int $v) use (&$checked) {
$checked++;
return $v > 3;
})->first();
echo $b, ' after ', $checked, ' tests', PHP_EOL;Picking one model out of a loaded relation
The relation is already in memory, so scanning it in PHP avoids a second query. The closure default only runs when no pending order exists, which keeps the fallback lookup off the common path. This snippet needs a booted application with Eloquent, so it is shown rather than executed.
<?php
$order = $customer->orders->first(
fn ($order) => $order->status === 'pending',
fn () => $customer->orders->last(),
);
return view('orders.show', ['order' => $order]);
Discussion