PHP: How do you get the first element of an array?

$array[0] is the obvious attempt. It only works for some arrays, though, and for the others you get either a warning or a silent null. Since PHP 7.3 there has been a function that covers every case.

The short answer

<?php
  $firstElement = $array[array_key_first($array)];
?>

array_key_first() has existed since PHP 7.3. It returns the first key, whatever that key looks like.

Why $array[0] is not enough

With a plain list it works. With an associative array it does not, and with a list that has gaps it does not either:

<?php
  $list  = ['a', 'b', 'c'];
  $assoc = ['x' => 10, 'y' => 20];
  $gap   = [5 => 'five', 9 => 'nine'];
?>

What array_key_first() makes of them:

array_key_first($list)   : 0
array_key_first($assoc)  : 'x'
array_key_first($gap)    : 5
array_key_first([])      : NULL

For $gap the first key is 5. So $gap[0] would raise a Warning: Undefined array key 0 — even though the array is not empty at all. This is exactly the situation you end up in after removing something from a list with unset().

And for the associative array:

$list[0]   : 'a'
$assoc[0]  : NULL  (caught with ??)
without ?? : raises a warning

What about reset()?

reset() is the answer you find most often. It is older than array_key_first() and it does work. There are two things you should know about it, though.

First, reset() modifies the array. More precisely: the internal pointer that every PHP array carries around with it.

pointer before reset : 'c'
reset($a)            : 'a'
pointer afterwards   : 'a'

array_key_first() does not touch the pointer. In most scripts that makes no difference, because since PHP 7 foreach no longer uses the pointer anyway. But if you work with current() and next() somewhere, it does make a difference.

Second, and this is the more important point:

reset([])            : false
reset([0])           : 0        <- falsy as well

Both return values are falsy. So if you check like this:

<?php
  $first = reset($array);
  if (!$first) {
    echo 'array is empty';   // not always true
  }
?>

… then you treat an array whose first element is 0 as if it were empty. The same goes for '', null and false as the first element.

array_key_first() does not have that problem:

array_key_first([])  : NULL
array_key_first([0]) : 0

null and 0 can be told apart cleanly with !== null.

current() without reset() is unreliable

You occasionally see current($array) without a preceding reset(). That only works by accident, namely as long as nobody has moved the pointer before:

after foreach, current() : 'a'

Here the pointer is still at the start, because in PHP 7+ foreach works on a copy. I would not rely on it — least of all if the array has been through somebody else’s code beforehand.

The remaining options

For completeness, they all work:

array_slice($assoc, 0, 1)         : {"x":10}
array_slice($assoc, 0, 1, true)   : {"x":10}  (keys preserved)
array_values($assoc)[0]           : 10

With array_values() you should be aware that PHP copies the entire array for it. With three elements that is irrelevant, with a hundred thousand it is not.

Incidentally, the fourth parameter of array_slice() makes no difference for string keys — those are always preserved. It only affects numeric keys.

And the last element?

The same way round:

<?php
  $lastElement = $array[array_key_last($array)];
?>
$assoc[array_key_last($assoc)] : 20

array_key_last() arrived in the same PHP version. The old way was end($array), with the same two caveats as reset().

Summary

  • $array[array_key_first($array)] is the option that covers every case.
  • $array[0] only works for gap-free lists.
  • array_key_first() returns null for an empty array — clearly distinguishable from the value 0.
  • reset() cannot do that and also modifies the internal pointer.
  • array_key_last() is the counterpart for the last element.

About Netcup (advertisement)

The German host Netcup offers, among other things, affordable and powerful web hosting packages, KVM-based root servers and dedicated servers. With our voucher codes you can save even more (6€ off your first order, 30% off all KVM-based root servers, ...).