Arrays7 min readExamples run on PHP 8.5.10

end()

Learn how PHP end() moves an array's internal pointer to the last element, what it returns, and why false can be ambiguous.

Signature

end(array|object &$array): mixed

Purpose

end() moves an array's internal pointer to its last element and returns that element's value. Every PHP array carries a hidden cursor, and functions such as current(), key(), next(), prev(), reset() and end() read or move it. end() is the quick way to peek at the final value of an array, and it leaves the cursor in a position from which you can walk backwards with prev().

Signature

Parameters

  • $array: the array whose pointer is moved. It is passed by reference, because the pointer is part of the array's state and the function changes it. There is no default value, and you must supply the argument.

Because of the reference, you must pass a real variable. Passing the direct result of a function call, such as end(explode(',', $text)), is a mistake: PHP reports a notice that only variables should be passed by reference. Store the result in a variable first.

The signature still lists object, but calling end() on an object has been deprecated since PHP 8.1. If you need the last property of an object, convert it with get_mangled_object_vars() first, or use a class designed for iteration such as ArrayIterator.

Return value and failure cases

end() returns the value of the last element, whatever its type. For an empty array it returns false. It does not throw an exception for an empty array.

This creates a real ambiguity. If the last element of a non-empty array is itself false, end() also returns false. The return value alone cannot tell you whether the array was empty or ended with false. When that distinction matters, check $array === [] first, or use array_key_last(), which returns null for an empty array and otherwise the last key.

Example 1: Reading the last value

The basic use is to fetch the last element. After the call, current() returns the same value, because the pointer now rests on that element.

Example
<?php
$fruits = ['apple', 'banana', 'cranberry'];
echo end($fruits), "\n";
echo current($fruits), "\n";
Output
cranberry
cranberry

Example 2: Avoiding the false ambiguity

A helper built on array_key_last() does not touch the internal pointer and tells an empty array apart from one that ends in false.

Example
<?php
function lastOrNull(array $items): mixed {
    $key = array_key_last($items);
    return $key === null ? null : $items[$key];
}

echo json_encode([lastOrNull([]), lastOrNull([1, false]), lastOrNull(['a' => 'x', 'b' => 'y'])]), "\n";
Output
[null,false,"y"]

Example 3: Moving the pointer around

With string keys, key() reports where end() landed. From there prev() steps backwards and reset() jumps to the first element.

Example
<?php
$stack = ['a' => 1, 'b' => 2, 'c' => 3];
$last = end($stack);
echo json_encode([$last, key($stack)]), "\n";
echo prev($stack), "\n";
echo reset($stack), "\n";
Output
[3,"c"]
2
1

Edge cases

  • Empty array: returns false, and the pointer has no element to rest on.
  • Single element: the first and last element are the same, so end() and reset() return the same value.
  • Non-sequential keys: end() follows insertion order, not key order. The last element is the one added last, even if its key is numerically smaller than others.
  • Copies: arrays are assigned by value, and the pointer position belongs to each array variable. Moving the pointer on one variable does not affect an earlier copy.
  • foreach: modern PHP's foreach does not depend on the internal pointer, so calling end() before or inside a loop does not change which elements the loop visits.

Common mistakes

  1. Passing a function result. Assign the array to a variable before calling end().
  2. Treating false as proof of an empty array. An array whose last element is false gives the same result.
  3. Forgetting the side effect. If other code later calls current() or next() on the same array, it starts from the last element, not the first. Call reset() when you need a known starting position.
  4. Using it only to get the last key. end() followed by key() works, but array_key_last() states the intent directly and leaves the pointer alone.
  5. Passing objects. This is deprecated since PHP 8.1, so convert to an array or use an iterator class.
  • reset() moves the pointer to the first element.
  • current() returns the element under the pointer.
  • key() returns the key under the pointer.
  • prev() and next() move the pointer one step.
  • array_key_last() returns the last key without moving the pointer.

Recap

end() takes an array variable by reference, moves its internal pointer to the last element and returns that value, or false for an empty array. Use it when you also want the pointer moved. If you only need the last value safely, array_key_last() avoids both the side effect and the false ambiguity.

Tested examples

Reading the last value
<?php
$fruits = ['apple', 'banana', 'cranberry'];
echo end($fruits), "\n";
echo current($fruits), "\n";
Output
cranberry
cranberry
Avoiding the false ambiguity
<?php
function lastOrNull(array $items): mixed {
    $key = array_key_last($items);
    return $key === null ? null : $items[$key];
}

echo json_encode([lastOrNull([]), lastOrNull([1, false]), lastOrNull(['a' => 'x', 'b' => 'y'])]), "\n";
Output
[null,false,"y"]
Moving the pointer around
<?php
$stack = ['a' => 1, 'b' => 2, 'c' => 3];
$last = end($stack);
echo json_encode([$last, key($stack)]), "\n";
echo prev($stack), "\n";
echo reset($stack), "\n";
Output
[3,"c"]
2
1