Arr::last
Returns the last array element, or the last one that passes a given truth test.
public static function last($array, ?callable $callback = null, $default = null)Parameters
| Parameter | Type | Description |
|---|---|---|
$$array | iterable | The array to inspect. Because the implementation calls array_reverse() and array_last(), it must be a real array in practice. |
$$callbackoptional | callable|null= null | Truth test receiving ($value, $key). When omitted, the final element is returned. |
$$defaultoptional | mixed= null | Returned when nothing passes the test. Passed through value(), so a Closure is invoked lazily. |
Return value
mixedThe last value that satisfies the callback, or the last element when no callback is given; otherwise the resolved default.
Errors
Raises a TypeError if a Generator or other non-array Traversable is passed, because array_reverse() and array_last() require an array.
Arr::last is the mirror of Arr::first. With no callback it simply hands back the final element. With a callback it reverses the array (preserving keys) and returns the first value from the end that satisfies the test.
When to reach for it
- Grabbing the most recent entry from an append-ordered log or history array.
- Finding the last threshold a value crossed — the last tier whose minimum is below a price, the last matching revision.
- Reading the final element of an array whose keys are not a clean
0..nlist, where$array[count($array) - 1]would be wrong.
What trips people up
The callback is called with ($value, $key) in that order, not ($key, $value). Only declare the second parameter if you need it.
The third argument is run through value(), so passing a Closure defers the work until it is actually needed — useful when the fallback is expensive to build. A Closure you meant to return as the value will be invoked instead, so wrap it: fn () => $theClosure.
The docblock says iterable, but the body reverses the array directly. Lazy sources have to be materialised with iterator_to_array() first.
Example
When to use it
- Pull the newest row out of an ordered event array without knowing its index.
- Find the last pricing tier whose threshold is under a given amount.
- Read the final element of an array with sparse or string keys.
Frequently asked questions
What is the difference between Arr::last and end()?
Arr::last does not move the array's internal pointer and accepts a truth test, while end() mutates the pointer and only ever gives you the final element. Arr::last also returns a default instead of false when the array is empty.
Does Arr::last return the key or the value?
It returns the value only. If you need the key of the last match, run the same callback over array_keys($array) instead.
Why does Arr::last fail on a generator?
Because the implementation calls array_reverse() and array_last(), both of which require a real array. Convert the generator with iterator_to_array() before passing it.
More examples
Keys are preserved while searching
Arr::last returns a value, never a key. The reversed scan reaches 'published' (90) before 'review' (40), so 90 wins. To recover the key, run the same test over array_keys().
<?php
use Illuminate\Support\Arr;
$statuses = [
'draft' => 10,
'review' => 40,
'published' => 90,
'archived' => 5,
];
// The callback sees the string key as its second argument.
$last = Arr::last($statuses, function (int $count, string $key) {
return $count > 20;
});
echo $last, PHP_EOL;
// Only the value is returned, never the key. Flip the search if you need it.
$key = Arr::last(array_keys($statuses), fn (string $k) => $statuses[$k] > 20);
echo $key, PHP_EOL;
/*
90
published
*/Last entry in an application log array
The default does not have to be a scalar. Returning a same-shaped array means the calling code can keep using array access without a null check.
<?php
use Illuminate\Support\Arr;
$attempts = [
['id' => 1, 'status' => 'failed', 'code' => 500],
['id' => 2, 'status' => 'failed', 'code' => 502],
['id' => 3, 'status' => 'success', 'code' => 200],
['id' => 4, 'status' => 'failed', 'code' => 503],
];
$lastSuccess = Arr::last(
$attempts,
fn (array $attempt) => $attempt['status'] === 'success',
['id' => null, 'status' => 'never succeeded', 'code' => 0]
);
echo $lastSuccess['id'], ' ', $lastSuccess['status'], PHP_EOL;
$lastTimeout = Arr::last(
$attempts,
fn (array $attempt) => $attempt['code'] === 504,
['status' => 'never timed out']
);
echo $lastTimeout['status'], PHP_EOL;
/*
3 success
never timed out
*/
Discussion