Arrays7 min readExamples run on PHP 8.5.10

reset()

Learn how PHP 8.4 reset() rewinds an array's internal pointer, returns the first value, and why empty arrays and false elements need care.

Signature

reset(array|object &$array): mixed

Purpose

Every PHP array carries an internal pointer, a hidden position that functions such as current(), next(), prev(), end() and key() read or move. reset() moves that pointer back to the first element and returns the value stored there. It is the standard way to say "start again from the beginning" when you work with pointer-based navigation. It is also a quick way to get the first value of an array whose keys you do not know.

Signature

Parameters and defaults

$array is the only parameter and it has no default. It is taken by reference, because the function changes the pointer stored with the variable. In practice you must pass a real variable. A literal array or the direct result of another function call cannot be passed by reference, so PHP raises an error instead of running the call. Assign the value to a variable first.

The signature also allows an object. Since PHP 8.1 calling reset() on an object is deprecated. The manual suggests converting the object with get_mangled_object_vars() first, or using a class that implements Iterator, such as ArrayIterator. For new code, treat reset() as an array function.

Return value and failure cases

reset() returns the value of the first element. If the array is empty it returns false. There is no exception for an empty array, so the failure signal is an ordinary return value.

That creates an ambiguity. An array whose first element really is false also makes reset() return false. A first element such as 0, '' or null is also falsy, so a loose check like if (reset($a)) can misjudge the array. Always compare with ===. To tell an empty array from one that starts with false, check count() first, or call key() after reset() and test whether it is null.

Example 1: rewinding after moving the pointer

The first example advances the pointer twice, then rewinds it. The value returned by reset() and the value read by current() afterwards are the same.

Example
<?php
$steps = ['step one', 'step two', 'step three'];
next($steps);
next($steps);
echo current($steps), "\n";
echo reset($steps), "\n";
echo current($steps), "\n";
Output
step three
step one
step one

Example 2: empty arrays and a leading false

Here reset() returns false for two different reasons. The value alone cannot distinguish them, but key() can. After reset() it is null for an empty array and the real first key otherwise.

Example
<?php
$empty = [];
$flags = [false, true];

echo json_encode([
    'empty' => reset($empty),
    'flags' => reset($flags),
    'emptyKey' => key($empty),
    'flagsKey' => key($flags),
]), "\n";
Output
{"empty":false,"flags":false,"emptyKey":null,"flagsKey":0}

Example 3: a first-or-default helper

This helper works with associative arrays and does not depend on the key names. It uses key() rather than the returned value to detect emptiness, so a first element of false is handled correctly. The array is passed by value to the helper, so the caller's variable is not the one being reset.

Example
<?php
function firstOr(array $items, string $default): string
{
    $first = reset($items);
    return key($items) === null ? $default : (string) $first;
}

echo firstOr(['b' => 'beta', 'a' => 'alpha'], 'none'), "\n";
echo firstOr([], 'none'), "\n";
echo firstOr([false, 'x'], 'none') === '' ? "empty-string\n" : "other\n";
Output
beta
none
empty-string

Edge cases

  • Associative arrays: reset() follows the array's internal order, which is insertion order, not key sorting. The first inserted element is returned.
  • Side effect on the variable: the pointer change is real. If other code later calls current() or next() on the same variable, it starts from the first element.
  • Looping: foreach does not depend on the internal pointer in modern PHP. You do not need reset() before a foreach loop. It matters only when you use current(), next(), prev(), end() or key() yourself.
  • Objects: passing an object is deprecated as of PHP 8.1, as noted above.

Common mistakes

  1. Testing the result loosely. if (reset($list)) fails for a first element of 0, '', '0', null or false. Use === false for emptiness, and confirm with key() or count() when false could be a real value.
  2. Passing a temporary value. Calling reset() directly on a function's return value cannot work because a reference is required. Store the result in a variable first.
  3. Using it just to read the first value. If you only want the first key, array_key_first() does not touch the pointer and avoids the side effect. You can then read the value with that key.
  4. Expecting a copy. The function changes the pointer of the variable you pass. It does not create a separate walker.
  • current() returns the element at the pointer.
  • next() and prev() move the pointer forward and back.
  • end() moves the pointer to the last element.
  • key() returns the key at the pointer, or null when the pointer is past the array.
  • array_key_first() finds the first key without moving the pointer.

Recap

reset() rewinds the internal pointer of an array and returns the first value, or false for an empty array. Pass a variable, not a literal, and avoid objects in new code. Compare with ===, and use key() or count() when a first element of false is possible.

Tested examples

Rewinding after moving the pointer
<?php
$steps = ['step one', 'step two', 'step three'];
next($steps);
next($steps);
echo current($steps), "\n";
echo reset($steps), "\n";
echo current($steps), "\n";
Output
step three
step one
step one
Empty arrays and a leading false
<?php
$empty = [];
$flags = [false, true];

echo json_encode([
    'empty' => reset($empty),
    'flags' => reset($flags),
    'emptyKey' => key($empty),
    'flagsKey' => key($flags),
]), "\n";
Output
{"empty":false,"flags":false,"emptyKey":null,"flagsKey":0}
A first-or-default helper
<?php
function firstOr(array $items, string $default): string
{
    $first = reset($items);
    return key($items) === null ? $default : (string) $first;
}

echo firstOr(['b' => 'beta', 'a' => 'alpha'], 'none'), "\n";
echo firstOr([], 'none'), "\n";
echo firstOr([false, 'x'], 'none') === '' ? "empty-string\n" : "other\n";
Output
beta
none
empty-string