PHP

Operador spaceship (<=>) en PHP

Autorangel cruz
Publicado
Lectura3 min de lectura
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; //  0

La 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/Carlos

Si 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.

El <=> es uno de los operadores menos conocidos de PHP. Los demás, en la guía de PHP.

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.

¿Tienes un proyecto en mente?

Trabajo con Laravel, WordPress, SEO técnico y servidores MCP. El primer paso es una llamada de descubrimiento, sin costo ni compromiso, donde me cuentas qué necesitas y te digo con honestidad si puedo ayudarte.

Hablemos