PHP: Wie holt man das erste Element eines Arrays?
$array[0] ist der naheliegende Versuch. Er funktioniert aber nur bei einem
Teil der Arrays, und bei den anderen bekommst du entweder eine Warnung oder
still null. Seit PHP 7.3 gibt es dafür eine Funktion, die alle Fälle
abdeckt.
Die kurze Antwort
<?php
$erstesElement = $array[array_key_first($array)];
?>
array_key_first() gibt es seit PHP 7.3. Sie liefert den ersten Schlüssel,
egal wie der aussieht.
Warum $array[0] nicht reicht
Bei einer einfachen Liste geht es gut. Bei einem assoziativen Array nicht, und bei einer Liste mit Lücken auch nicht:
<?php
$liste = ['a', 'b', 'c'];
$assoc = ['x' => 10, 'y' => 20];
$luecke = [5 => 'fuenf', 9 => 'neun'];
?>
Was array_key_first() daraus macht:
array_key_first($liste) : 0
array_key_first($assoc) : 'x'
array_key_first($luecke) : 5
array_key_first([]) : NULL
Bei $luecke ist der erste Schlüssel die 5. $luecke[0] würde also eine
Warning: Undefined array key 0 auslösen — obwohl das Array gar nicht leer
ist. Genau dieser Fall tritt auf, nachdem man mit unset() etwas aus einer
Liste entfernt hat.
Und beim assoziativen Array:
$liste[0] : 'a'
$assoc[0] : NULL (mit ?? abgefangen)
ohne ?? : löst eine Warning aus
Was ist mit reset()?
reset() ist die Antwort, die man am häufigsten findet. Sie ist älter als
array_key_first() und funktioniert auch. Zwei Dinge sollte man aber wissen.
Erstens verändert reset() das Array. Genauer: den internen Zeiger, den
jedes PHP-Array mit sich herumträgt.
aktueller Zeiger vor reset : 'c'
reset($a) : 'a'
aktueller Zeiger danach : 'a'
array_key_first() fasst den Zeiger nicht an. In den meisten Skripten ist das
egal, weil foreach den Zeiger seit PHP 7 ohnehin nicht mehr benutzt. Wenn du
aber irgendwo mit current() und next() arbeitest, dann ist es nicht egal.
Zweitens, und das ist der wichtigere Punkt:
reset([]) : false
reset([0]) : 0 <- ebenfalls falsy
Beide Rückgabewerte sind falsy. Wenn du also so prüfst:
<?php
$erstes = reset($array);
if (!$erstes) {
echo 'Array ist leer'; // stimmt nicht immer
}
?>
… dann behandelst du ein Array, dessen erstes Element den Wert 0 hat, wie ein
leeres. Dasselbe gilt für '', null und false als erstes Element.
array_key_first() hat das Problem nicht:
array_key_first([]) : NULL
array_key_first([0]) : 0
null gegen 0 lässt sich mit !== null sauber unterscheiden.
current() ohne reset() ist unzuverlässig
Man sieht gelegentlich current($array) ohne vorheriges reset(). Das
funktioniert nur zufällig, nämlich solange den Zeiger vorher niemand bewegt hat:
nach foreach, current() : 'a'
Hier steht der Zeiger noch am Anfang, weil foreach in PHP 7+ auf einer Kopie
arbeitet. Verlassen würde ich mich darauf nicht — schon gar nicht, wenn das
Array vorher durch fremden Code gelaufen ist.
Die übrigen Wege
Der Vollständigkeit halber, sie funktionieren alle:
array_slice($assoc, 0, 1) : {"x":10}
array_slice($assoc, 0, 1, true) : {"x":10} (Schlüssel behalten)
array_values($assoc)[0] : 10
Bei array_values() sollte man wissen, dass PHP dafür das komplette Array
kopiert. Bei drei Elementen ist das egal, bei hunderttausend nicht.
Der vierte Parameter von array_slice() macht bei String-Schlüsseln übrigens
keinen Unterschied — die bleiben immer erhalten. Er wirkt nur auf numerische
Schlüssel.
Und das letzte Element?
Analog dazu:
<?php
$letztesElement = $array[array_key_last($array)];
?>
$assoc[array_key_last($assoc)] : 20
array_key_last() kam in derselben PHP-Version dazu. Der alte Weg dafür war
end($array), mit denselben zwei Einschränkungen wie bei reset().
Zusammenfassung
$array[array_key_first($array)]ist der Weg, der alle Fälle abdeckt.$array[0]funktioniert nur bei lückenlosen Listen.array_key_first()liefert bei einem leeren Arraynull— eindeutig unterscheidbar vom Wert0.reset()kann das nicht und verändert außerdem den internen Zeiger.array_key_last()ist das Gegenstück für das letzte Element.
Hinweis zu Netcup (Werbung)
Der deutsche Hoster Netcup bietet unter anderem günstige und zugleich leistungsstarke Webhosting Pakete, KVM-basierte Root Server und dezidierte Server an. Mit unseren Gutscheincodes kannst du noch mehr Geld sparen (6€ bei deiner ersten Bestellung, 30% Rabatt auf alle KVM-basierten Root Server, ...).