Null coalescing en PHP: el operador ?? y ??=

El operador null coalescing (??), o de fusión de null, devuelve su operando izquierdo si existe y no es null; de lo contrario, devuelve el derecho. Sirve para dar valores por defecto sin que PHP lance un warning cuando la variable no está definida. Desde PHP 7.4 existe además ??=, que asigna el valor por defecto solo cuando la variable es null o no existe.
Este artículo forma parte de la guía de operadores en PHP. Aquí me enfoco en ?? y ??= y en cómo se diferencian del Elvis.
El problema que resuelve ??
Leer una clave que puede no existir —de $_GET, de un array de configuración, de una respuesta de API— obligaba a verificar con isset() para evitar el warning "Undefined array key":
// Antes: verificación manual con isset
$nombre = isset($_GET['nombre']) ? $_GET['nombre'] : 'Invitado';
// Con null coalescing: mismo resultado, sin warning
$nombre = $_GET['nombre'] ?? 'Invitado';$_GET['nombre'] ?? 'Invitado' equivale exactamente a isset($_GET['nombre']) ? $_GET['nombre'] : 'Invitado', pero en una expresión limpia. Si la clave no existe o es null, devuelve 'Invitado' sin quejarse.
Encadenamiento: el primer valor que exista
?? se puede encadenar. PHP evalúa de izquierda a derecha y devuelve el primer operando que no sea null:
// Busca el tema en preferencias del usuario, luego en config global, luego un default
$tema = $userConfig['theme'] ?? $appConfig['theme'] ?? 'dark';Es uno de los patrones más útiles de PHP 7+: una sola línea recorre varias fuentes de fallback en orden de prioridad.
??= : asignar solo si está vacío
El operador de asignación coalescente (??=, PHP 7.4+) asigna el valor de la derecha solo si la variable de la izquierda es null o no existe. Si ya tiene un valor, lo deja intacto:
$opciones['timeout'] ??= 30;
// Asigna 30 solo si 'timeout' no estaba definido o era null.
// Equivale a: $opciones['timeout'] = $opciones['timeout'] ?? 30;Es ideal para rellenar valores por defecto en un array de configuración sin pisar lo que el usuario ya definió.
La diferencia clave: ?? vs ?: (Elvis)
Aquí es donde la mayoría se confunde. El operador Elvis (?:) y el null coalescing (??) parecen lo mismo, pero chequean cosas distintas:
?:evalúa truthiness: dispara el fallback con cualquier valor falsy ("",0,"0",[],false,null).??solo mira si el valor esnullo no existe. Un""o un0se consideran valores válidos y no disparan el fallback.
$valor = "";
echo $valor ?: 'fallback'; // "fallback" — "" es falsy
echo $valor ?? 'fallback'; // "" — "" no es null, es un valor válido| Situación | ?: (Elvis) |
?? (null coalescing) |
|---|---|---|
| Variable no definida | warning + fallback | fallback, sin warning |
Valor "" o 0 |
fallback (es falsy) | devuelve "" o 0 |
Valor null |
fallback | fallback |
La regla: en formularios y datos donde "" o 0 son valores legítimos, usa ??. Solo usa ?: cuando de verdad quieres tratar lo falsy como "vacío".
Combinarlo con el operador nullsafe ?->
Desde PHP 8, el operador nullsafe (?->) corta una cadena de propiedades o métodos si algo es null, en vez de tirar un error. Combinado con ??, da una expresión muy expresiva para navegar objetos que pueden no existir:
// Si $usuario, su dirección o su ciudad son null, el resultado es 'desconocida'
$ciudad = $usuario?->direccion?->ciudad ?? 'desconocida';El ?-> evita el error al acceder a propiedades de null, y el ?? provee el valor por defecto final.
Preguntas frecuentes
¿Qué hace el operador ?? en PHP?
Devuelve su operando izquierdo si existe y no es null; en caso contrario, devuelve el derecho. Sirve para asignar valores por defecto sin generar warnings: $nombre = $_GET['user'] ?? 'anónimo';.
¿Cuál es la diferencia entre ?? y ?:?
?: (Elvis) dispara el fallback con cualquier valor falsy ("", 0, null…), mientras que ?? solo lo hace cuando el valor es null o no existe. Además, ?? no genera warning si la variable no está definida y ?: sí.
¿Qué es ??= en PHP?
Es el operador de asignación coalescente (PHP 7.4+). $a ??= $b asigna $b a $a solo si $a es null o no existe. Equivale a $a = $a ?? $b pero sin repetir la variable.
¿?? genera un warning si la variable no existe?
No. Esa es justamente su ventaja sobre isset() manual o el Elvis: accede a la variable de forma segura y devuelve el fallback sin emitir "Undefined variable" ni "Undefined array key".
Cierre
El null coalescing es el operador al que recurres cada vez que un valor puede faltar: ?? para leer con un default seguro, ??= para rellenar sin pisar, y encadenado para recorrer fuentes en orden de prioridad. La clave es no confundirlo con el Elvis: ?? mira null, ?: mira truthiness. Para el resto de operadores del lenguaje, vuelve a la guía de operadores en PHP.