Arr::last

Returns the last array element, or the last one that passes a given truth test.

Signature
public static function last($array, ?callable $callback = null, $default = null)

Parameters

ParameterTypeDescription
$$arrayiterableThe array to inspect. Because the implementation calls array_reverse() and array_last(), it must be a real array in practice.
$$callbackoptionalcallable|null= nullTruth test receiving ($value, $key). When omitted, the final element is returned.
$$defaultoptionalmixed= nullReturned 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..n list, 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

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

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().

Example · php
<?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.

Example · php
<?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

  • Be the first to comment on this lesson.