Wer ist Elvis und was hat er mit PHP zu tun?
\n\nWenn Sie schon einmal in PHP programmiert haben, sind Ihnen in fremdem Code sicherlich seltsame Konstrukte aufgefallen: $name ?: 'Gast' oder $name ?? 'Gast'. Auf den ersten Blick – dasselbe. Aber tatsächlich verbergen sich hinter diesen beiden Operatoren völlig unterschiedliche Mechanismen, die Ihren Code sowohl retten als auch ein Ei ins Nest legen können.
Auf Stack Overflow hat die Frage "PHP short-ternary ("Elvis") operator vs null coalescing operator" Zehntausende von Aufrufen gesammelt. Und das nicht ohne Grund. Entwickler werden verwirrt, machen Fehler und suchen dann lange nach Bugs. Lassen Sie uns ein für alle Mal klären, wer wer ist, und aufhören zu raten.
\n\nIn diesem Artikel werden wir nicht nur die Unterschiede auflisten. Wir werden unter die Haube von PHP schauen, uns reale Fälle aus der Produktion ansehen und verstehen, wann welcher Operator verwendet werden sollte. Los geht's!
\n\nKurze Einführung: Was ist das überhaupt?
\n\nTernärer Operator (klassisch)
\nErinnern wir uns zunächst an die Grundlagen. Der ternäre Operator ist eine Kurzform von if-else:
\n\n$age = 20;\n$status = ($age >= 18) ? 'Erwachsen' : 'Kind';\n// $status = 'Erwachsen'\n\nGanz einfach: Wenn die Bedingung wahr ist – nimm den ersten Wert, sonst den zweiten.
\n\nShort-Ternary (auch Elvis-Operator) — ?:
\nDies ist eine Abkürzung für den Fall, dass Sie eine Variable auf "Wahrheit" prüfen und ihren eigenen Wert verwenden möchten:
\n\n$name = 'Alexei';\n$greeting = $name ?: 'Gast';\n// $greeting = 'Alexei'\n\n$name = '';\n$greeting = $name ?: 'Gast';\n// $greeting = 'Gast'\n\nFunktioniert so: Wenn $name zu true ausgewertet wird, nehmen wir $name. Sonst – "Gast".
Null-Coalescing-Operator — ??
\nErschien in PHP 7.0 und wurde sofort zum Liebling der Entwickler:
\n\n$name = 'Alexei';\n$greeting = $name ?? 'Gast';\n// $greeting = 'Alexei'\n\n$name = null;\n$greeting = $name ?? 'Gast';\n// $greeting = 'Gast'\n\nUnterschied zu Elvis: Die Prüfung erfolgt nur auf null, nicht auf "Falschheit" im Allgemeinen.
\n\nDer Hauptunterschied: Was gilt als "leer"?
\n\nHier wird es richtig interessant. Schauen wir uns eine Vergleichstabelle für verschiedene Werte von $value an:
$value = false;\necho $value ?: 'default'; // 'default' (false ist "falsch")\necho $value ?? 'default'; // false (false ist NICHT null)\n\n$value = 0;\necho $value ?: 'default'; // 'default' (0 ist "falsch")\necho $value ?? 'default'; // 0 (0 ist NICHT null)\n\n$value = '';\necho $value ?: 'default'; // 'default' (leerer String ist "falsch")\necho $value ?? 'default'; // '' (leerer String ist NICHT null)\n\n$value = [];\necho $value ?: 'default'; // 'default' (leeres Array ist "falsch")\necho $value ?? 'default'; // [] (leeres Array ist NICHT null)\n\n$value = '0';\necho $value ?: 'default'; // 'default' (String "0" ist "falsch"!)\necho $value ?? 'default'; // '0' (String "0" ist NICHT null)\n\nSehen Sie den Unterschied? Elvis arbeitet als Prüfung auf "Wahrheit" (truthy/falsy), während Null Coalescing eine strenge Prüfung auf Existenz und Unterschied zu null ist.
\n\nUnter der Haube: Wie funktioniert das auf Engine-Ebene
\n\nWerfen wir einen Blick in die PHP-Quellen (na ja, fast). Wenn Sie jemals PHP aus den Quellen kompiliert haben, wissen Sie, dass beide Operatoren während der Parsing-Phase verarbeitet werden.
\n\nShort-Ternary (?):
\nEigentlich ist das syntaktischer Zucker. $a ?: $b wird zu $a ? $a : $b. Aber es gibt eine Nuance: PHP berechnet $a nicht zweimal. Es speichert das Ergebnis in einer temporären Variable. Dies ist wichtig für Funktionen mit Seiteneffekten:
function getData() {\n echo "Funktion aufgerufen!\\n";\n return rand(0, 1) ? 'data' : '';\n}\n\n// Elvis ruft die Funktion EINMAL auf\n$result = getData() ?: 'default';\n// "Funktion aufgerufen!" — einmal\n\nWenn PHP $a zweimal berechnen würde,