Qui est Elvis et quel rapport avec PHP ?
\n\nSi vous avez déjà écrit du PHP, vous avez sûrement vu des constructions étranges dans le code des autres : $name ?: 'Invité' ou $name ?? 'Invité'. À première vue, c'est la même chose. Mais en réalité, ces deux opérateurs cachent des mécaniques complètement différentes, qui peuvent aussi bien sauver votre code que vous causer des ennuis.
Sur Stack Overflow, la question "Opérateur PHP short-ternary ("Elvis") vs opérateur null coalescing" a rassemblé des dizaines de milliers de vues. Et ce n'est pas un hasard. Les développeurs s'embrouillent, font des erreurs, puis passent du temps à chercher des bugs. Mettons les choses au clair une fois pour toutes, et arrêtons de deviner.
\n\nDans cet article, nous ne nous contenterons pas d'énumérer les différences. Nous allons regarder sous le capot de PHP, examiner des cas réels de production et comprendre quel opérateur utiliser quand. C'est parti !
\n\nPetit rappel : de quoi s'agit-il exactement ?
\n\nL'opérateur ternaire (classique)
\nPour commencer, rappelons les bases. L'opérateur ternaire est une forme raccourcie de if-else :
\n\n$age = 20;\n$status = ($age >= 18) ? 'Adulte' : 'Enfant';\n// $status = 'Adulte'\n\nSimple : si la condition est vraie, on prend la première valeur, sinon la seconde.
\n\nShort-ternary (alias opérateur Elvis) — ?:
\nC'est un raccourci pour le cas où vous vérifiez si une variable est "vraie" et souhaitez utiliser sa valeur :
\n\n$name = 'Alexis';\n$greeting = $name ?: 'Invité';\n// $greeting = 'Alexis'\n\n$name = '';\n$greeting = $name ?: 'Invité';\n// $greeting = 'Invité'\n\nFonctionnement : si $name est évalué à true, on prend $name. Sinon, on prend "Invité".
L'opérateur Null coalescing — ??
\nApparu en PHP 7.0, il est rapidement devenu le chouchou des développeurs :
\n\n$name = 'Alexis';\n$greeting = $name ?? 'Invité';\n// $greeting = 'Alexis'\n\n$name = null;\n$greeting = $name ?? 'Invité';\n// $greeting = 'Invité'\n\nDifférence avec Elvis : la vérification porte uniquement sur null, et non sur la "fausseté" en général.
\n\nLa différence principale : qu'est-ce qui est considéré comme "vide" ?
\n\nC'est là que les choses deviennent intéressantes. Regardons un tableau comparatif pour différentes valeurs de $value :
$value = false;\necho $value ?: 'default'; // 'default' (false est "faux")\necho $value ?? 'default'; // false (false n'est PAS null)\n\n$value = 0;\necho $value ?: 'default'; // 'default' (0 est "faux")\necho $value ?? 'default'; // 0 (0 n'est PAS null)\n\n$value = '';\necho $value ?: 'default'; // 'default' (chaîne vide est "faux")\necho $value ?? 'default'; // '' (chaîne vide n'est PAS null)\n\n$value = [];\necho $value ?: 'default'; // 'default' (tableau vide est "faux")\necho $value ?? 'default'; // [] (tableau vide n'est PAS null)\n\n$value = '0';\necho $value ?: 'default'; // 'default' (la chaîne "0" est "faux" !)\necho $value ?? 'default'; // '0' (la chaîne "0" n'est PAS null)\n\nVous voyez la différence ? Elvis fonctionne comme une vérification de vérité (truthy/falsy), tandis que null coalescing est une vérification stricte d'existence et de différence par rapport à null.
\n\nSous le capot : comment ça fonctionne au niveau du moteur
\n\nRegardons dans les sources de PHP (enfin, presque). Si vous avez déjà compilé PHP à partir des sources, vous savez que les deux opérateurs sont traités lors de l'étape d'analyse syntaxique.
\n\nShort-ternary (?):
\nEn réalité, c'est du sucre syntaxique. $a ?: $b se transforme en $a ? $a : $b. Mais il y a une nuance : PHP n'évalue pas $a deux fois. Il stocke le résultat dans une variable temporaire. C'est important pour les fonctions avec effets de bord :
function getData() {\n echo "Fonction appelée !\\n";\n return rand(0, 1) ? 'data' : '';\n}\n\n// Elvis appelle la fonction UNE SEULE fois\n$result = getData() ?: 'default';\n// "Fonction appelée !" — une seule fois\n\nSi PHP évaluait $a deux fois,