Elvis vive: comparación de short-ternary y null coalescing en PHP

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

¿Quién es Elvis y qué tiene que ver con PHP?

\n\n

Si alguna vez has escrito en PHP, seguramente has visto construcciones extrañas en código ajeno: $name ?: 'Invitado' o $name ?? 'Invitado'. A simple vista, parecen lo mismo. Pero en realidad, detrás de estos dos operadores se esconden mecánicas completamente diferentes que pueden tanto salvar tu código como meterte en problemas.

\n\n

En Stack Overflow, la pregunta "Operador short-ternary ("Elvis") de PHP vs operador null coalescing" ha acumulado decenas de miles de visitas. Y no es casualidad. Los desarrolladores se confunden, cometen errores y luego pasan mucho tiempo buscando bugs. Aclaremos de una vez por todas quién es quién y dejemos de adivinar.

\n\n

En este artículo no solo enumeraremos las diferencias. Echaremos un vistazo bajo el capó de PHP, veremos casos reales de producción y entenderemos cuándo usar cada operador. ¡Allá vamos!

\n\n

Breve introducción: ¿qué son exactamente?

\n\n

Operador ternario (clásico)

\n

Para empezar, recordemos lo básico. El operador ternario es una forma abreviada de if-else:

\n\n
$age = 20;\n$status = ($age >= 18) ? 'Adulto' : 'Niño';\n// $status = 'Adulto'
\n\n

Simple: si la condición es verdadera, tomamos el primer valor; de lo contrario, el segundo.

\n\n

Short-ternary (también conocido como operador Elvis) — ?:

\n

Es una abreviatura para cuando verificas si una variable es "verdadera" y quieres usar su propio valor:

\n\n
$name = 'Alex';\n$greeting = $name ?: 'Invitado';\n// $greeting = 'Alex'\n\n$name = '';\n$greeting = $name ?: 'Invitado';\n// $greeting = 'Invitado'
\n\n

Funciona así: si $name se evalúa como true, tomamos $name. De lo contrario, "Invitado".

\n\n

Operador null coalescing — ??

\n

Apareció en PHP 7.0 y rápidamente se convirtió en el favorito de los desarrolladores:

\n\n
$name = 'Alex';\n$greeting = $name ?? 'Invitado';\n// $greeting = 'Alex'\n\n$name = null;\n$greeting = $name ?? 'Invitado';\n// $greeting = 'Invitado'
\n\n

Diferencia con Elvis: la verificación es solo contra null, no contra "falsedad" en general.

\n\n

La diferencia principal: ¿qué se considera "vacío"?

\n\n

Aquí es donde se pone interesante. Veamos una tabla comparativa para diferentes valores de $value:

\n\n
$value = false;\necho $value ?: 'default'; // 'default' (false es "falso")\necho $value ?? 'default'; // false (false NO es null)\n\n$value = 0;\necho $value ?: 'default'; // 'default' (0 es "falso")\necho $value ?? 'default'; // 0 (0 NO es null)\n\n$value = '';\necho $value ?: 'default'; // 'default' (cadena vacía es "falso")\necho $value ?? 'default'; // '' (cadena vacía NO es null)\n\n$value = [];\necho $value ?: 'default'; // 'default' (array vacío es "falso")\necho $value ?? 'default'; // [] (array vacío NO es null)\n\n$value = '0';\necho $value ?: 'default'; // 'default' (cadena "0" es "falso"!)\necho $value ?? 'default'; // '0' (cadena "0" NO es null)
\n\n

¿Ves la diferencia? Elvis funciona como una verificación de "veracidad" (truthy/falsy), mientras que null coalescing es una verificación estricta de existencia y diferencia de null.

\n\n

Bajo el capó: cómo funciona a nivel del motor

\n\n

Echemos un vistazo al código fuente de PHP (bueno, casi). Si alguna vez has compilado PHP desde el código fuente, sabrás que ambos operadores se procesan en la etapa de análisis sintáctico.

\n\n

Short-ternary (?):

\n

En realidad, es azúcar sintáctico. $a ?: $b se convierte en $a ? $a : $b. Pero hay un detalle: PHP no evalúa $a dos veces. Guarda el resultado en una variable temporal. Esto es importante para funciones con efectos secundarios:

\n\n
function getData() {\n    echo "¡Función llamada!\\n";\n    return rand(0, 1) ? 'data' : '';\n}\n\n// Elvis llama a la función UNA vez\n$result = getData() ?: 'default';\n// "¡Función llamada!" — una vez
\n\n

Si PHP evaluara $a dos veces,

Blogs

Book Recommendations