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()returnsnullfor an empty array — clearly distinguishable from the value0.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, ...).