PHP: isset vs. array_key_exists

Heute möchte ich mal ein paar Worte zu den Funktionen isset und array_key_exists loswerden. Genauer angeschaut habe ich mir das Verhalten der beiden Funktionen beim Prüfen ob ein Feld in einem Array existiert. Bevor ich zur Performance komme möchte ich jedoch noch auf ein paar Besonderheiten der Funktionen eingehen:

Um zu prüfen ob ein Feld in einem Array existiert ohne dabei Fehlermeldungen zu erzeugen muss vor beiden Funktionen isset und is_array aufgerufen werden.

Beispiel:

if(isset($foo) && is_array($foo) && isset($foo['bar']))
{
    $check = true;
}
if(isset($foo) && is_array($foo) && array_key_exists('bar', $foo))
{
    $check = true;
}

Der Grund hierfür ist nicht immer direkt ersichtlich, deswegen hier die Erklärung: isset erzeugt zwar keine Notices oder Warnings falls die Variable $foo nicht gesetzt ist, aber es gibt ein anderes Problem. Wenn die Variable $foo vom Typ String ist würde die Prüfung auf ein Array-Feld mit isset true liefern.

Beispiel:

$foo = 'bar';
var_dump(isset($foo['bar'])); // true

Dieses Verhalten erklärt die Notwendigkeit von is_array vor dem Prüfen mit isset. Das isset vor dem is_array ist schließlich notwendig weil is_array eine Notice erzeugt wenn die zu prüfende Variable nicht gesetzt ist.

Die Funktion array_key_exists erzeugt ein Warning falls das zu prüfende Array nicht existiert oder die übergebene Variable nicht vom Typ Array ist. Somit ist hier ebenfalls die Nutzung von is_array in Kombination mit isset zu empfehlen.

Mit obiger Syntax lässt sich nun eigentlich in beide Fällen prüfen ob ein Feld im einem Array existiert. Dabei ist jedoch eine Ausnahme zu beachten, und zwar der Wert null in einem Array.

Beispiel:

$foo['bar'] = null;
var_dump(isset($foo['bar'])); // false
var_dump(array_key_exists('bar', $foo)); // true

Damit sollte die Verwendung der beiden Funktionen geklärt sein (falls nicht bitte ich um einen kurzen Kommentar), aber es bleibt die Frage: Welche der beiden Varianten ist schneller, isset oder array_key_exists? Hier das Ergebnis:

performance_array_key_exists performance_isset

Klare Sache: isset ist wesentlich schneller als array_key_exists, 10000 Prüfungen dauert nur etwa halb so lange. Zudem fallen zwei weitere Dinge auf: isset taucht nicht in den Xdebug Ergebnissen auf. Die Begründung ist relativ simpel. Da isset keine Funktion ist sondern lediglich ein Sprachkonstrukt, taucht dieses nicht in den Xdebug-Listings auf. Weiterhin fällt auf, dass is_array fast genauso viel Zeit in Anspruch nimmt wie array_key_exists. Hierfür habe ich leider keine Erklärung, denn ich hätte erwarten dass array_key_exists im Gegensatz zu is_array eine Array-Funktion und damit wesentlich langsamer ist. Falls jemand eine Erklärung hat: Immer her damit!