Operador spaceship (<=>) en PHP

El operador spaceship (<=>), o nave espacial, llegó con PHP 7 y compara dos valores devolviendo un entero: menor que cero si el izquierdo es menor, cero si son iguales, mayor que cero si el izquierdo es mayor (en la práctica, -1, 0 o 1). Su uso principal es ordenar arrays con usort en una sola línea.
Este artículo forma parte de la guía de operadores en PHP. Aquí me enfoco en cómo funciona y para qué sirve de verdad.
Qué devuelve <=>
echo 1 <=> 2; // -1 (izquierdo menor)
echo 2 <=> 2; // 0 (iguales)
echo 3 <=> 2; // 1 (izquierdo mayor)
echo "a" <=> "b"; // -1 (orden alfabético)
echo 1.5 <=> 1.5; // 0La especificación dice "un entero menor, igual o mayor que cero", no necesariamente -1/1. En la práctica PHP devuelve -1, 0 o 1, pero tu código no debería depender del valor exacto: lo que importa es el signo.
El spaceship usa las mismas reglas de comparación que <, > y compañía. Compara números como números, strings de forma lexicográfica, y sigue las reglas estándar de PHP para tipos mixtos. No es para comprobar igualdad (para eso está ===): es para ordenar.
El motivo de existir: ordenar con usort
usort necesita una función que, dados dos elementos, diga cuál va primero devolviendo un número negativo, cero o positivo. Eso es exactamente lo que produce el spaceship. Antes de PHP 7, esa función era verbosa:
// Antes de PHP 7
usort($numeros, function ($a, $b) {
if ($a === $b) return 0;
return ($a < $b) ? -1 : 1;
});
// Con el spaceship: una línea
usort($numeros, fn($a, $b) => $a <=> $b);Orden ascendente y descendente
La dirección del orden depende de qué operando va a la izquierda. Para invertirlo, invierte los operandos:
$numeros = [3, 1, 4, 1, 5, 9, 2, 6];
usort($numeros, fn($a, $b) => $a <=> $b);
// Ascendente: [1, 1, 2, 3, 4, 5, 6, 9]
usort($numeros, fn($a, $b) => $b <=> $a);
// Descendente: [9, 6, 5, 4, 3, 2, 1, 1]Ordenar arrays de datos por un campo
El caso real más común: ordenar una lista de registros por una propiedad.
$usuarios = [
['nombre' => 'Ana', 'edad' => 30],
['nombre' => 'Luis', 'edad' => 25],
['nombre' => 'Eva', 'edad' => 35],
];
usort($usuarios, fn($a, $b) => $a['edad'] <=> $b['edad']);
// Por edad ascendente: Luis (25), Ana (30), Eva (35)Funciona igual con objetos: fn($a, $b) => $a->edad <=> $b->edad.
Ordenar por varios criterios
Aquí brilla la combinación con el operador Elvis (?:). Como <=> devuelve 0 cuando los valores son iguales (y 0 es falsy), el ?: deja pasar la comparación a la siguiente:
$personas = [
['apellido' => 'Pérez', 'nombre' => 'Ana'],
['apellido' => 'García', 'nombre' => 'Luis'],
['apellido' => 'Pérez', 'nombre' => 'Carlos'],
];
usort($personas, fn($a, $b) =>
$a['apellido'] <=> $b['apellido'] // primero por apellido
?: $a['nombre'] <=> $b['nombre'] // si empatan, desempata por nombre
);
// García/Luis, Pérez/Ana, Pérez/CarlosSi el apellido es igual, la primera comparación da 0 y el ?: evalúa la segunda. Puedes encadenar tantos criterios como necesites.
Spaceship con strings, arrays y objetos
// Strings: comparación lexicográfica
echo "manzana" <=> "naranja"; // -1
// Arrays: primero por cantidad de elementos, luego elemento a elemento
echo [1, 2, 3] <=> [1, 2, 3]; // 0
echo [1, 2, 3] <=> [1, 2, 1]; // 1
// Objetos: compara los atributos (deben ser de la misma clase)Con strings numéricas aplican las reglas de comparación de PHP 8 (dos strings numéricas se comparan como números), igual que con ==. Si necesitas un orden de strings que no dependa de eso, conviértelas a un tipo explícito antes de comparar.
Preguntas frecuentes
¿Qué devuelve el operador <=> en PHP?
Un entero: menor que cero si el operando izquierdo es menor, cero si son iguales, y mayor que cero si el izquierdo es mayor. En la práctica, -1, 0 o 1. Lo relevante es el signo, no el valor exacto.
¿Para qué sirve el operador spaceship?
Sobre todo para escribir funciones de comparación en usort, uasort y uksort. Reemplaza el típico bloque if-else que devolvía -1, 0 o 1 por una sola expresión.
¿Cómo ordeno de mayor a menor con el spaceship?
Invierte los operandos: fn($a, $b) => $b <=> $a ordena descendente, mientras que $a <=> $b ordena ascendente.
¿Sirve <=> para comparar igualdad?
No. Para saber si dos valores son iguales usa == o ===. El spaceship está pensado para ordenar, no para condiciones booleanas. Repaso la diferencia en == vs ===.
Cierre
El operador spaceship convierte la tarea repetitiva de escribir funciones de comparación en una sola expresión legible: $a <=> $b para ascendente, $b <=> $a para descendente, y ?: encadenados para ordenar por varios criterios. Es un operador de nicho —vive casi siempre dentro de usort—, pero cuando lo necesitas, ahorra mucho ruido. Para el resto de operadores del lenguaje, vuelve a la guía de operadores en PHP.