planeta jupiter planeta tierra

match frente a switch en PHP: cuál usar y por qué

· 6 min de lectura · PHP

La palabra match con un ejemplo de código
nave extraterrestre
La palabra match con un ejemplo de código

PHP 8 trajo match, y mucha gente lo ve como «un switch más corto». Es más que eso: compara de forma estricta, devuelve un valor, no necesita break y te avisa si se te olvida un caso. Vamos a ver las diferencias con ejemplos sencillos y cuándo sigue teniendo sentido el switch.

Explicación

El mismo código, primero con switch:

switch ($status) {
    case 'pending':
        $label = 'Pendiente';
        break;
    case 'paid':
        $label = 'Pagado';
        break;
    default:
        $label = 'Desconocido';
}

Y con match:

$label = match ($status) {
    'pending' => 'Pendiente',
    'paid'    => 'Pagado',
    default   => 'Desconocido',
};

De nueve líneas a cinco, y sin repetir $label = en cada caso. Pero lo importante no es que sea más corto, sino que se comporta distinto.

Las diferencias

1. match devuelve un valor

switch ejecuta código; match es una expresión, como una suma o una llamada a función. Por eso lo puedes asignar, devolver o pasar como argumento directamente:

return match ($status) {
    'pending' => 'Pendiente',
    'paid'    => 'Pagado',
    default   => 'Desconocido',
};

2. Compara con ===, no con ==

switch compara «por encima» (==) y match de forma estricta (===): el valor y el tipo tienen que coincidir.

$page = '1'; // viene de la URL: siempre es un string

switch ($page) {
    case 1:
        echo 'primera'; // entra: '1' == 1
        break;
}

echo match ($page) {
    1       => 'primera',
    default => 'otra', // sale 'otra': '1' !== 1
};

Casi siempre es lo que quieres, pero ojo con lo que llega de formularios y URLs: si comparas con números, convierte antes con (int) $page.

3. No hay break (ni bugs por olvidarlo)

En un switch, si te olvidas un break, la ejecución «se cae» al caso siguiente:

switch ($status) {
    case 'pending':
        $label = 'Pendiente';
        // falta el break...
    case 'paid':
        $label = 'Pagado'; // ...y un pedido pendiente acaba como «Pagado»
        break;
}

En match cada caso es independiente: se ejecuta uno y se acabó.

4. Si no encaja ningún caso, falla

Un switch sin default que no encuentra nada simplemente no hace nada, y sigues adelante con una variable sin asignar. match lanza un UnhandledMatchError:

$label = match ($status) {
    'pending' => 'Pendiente',
    'paid'    => 'Pagado',
};

// con $status = 'shipped':
// UnhandledMatchError: Unhandled match case 'shipped'

Parece peor, pero es mejor: te enteras del caso que se te olvidó en la línea exacta, en vez de tres pantallas más allá. Con enums es donde más luce: si añades un caso nuevo al enum y no lo contemplas, el match te lo dice.

5. Varios valores en un mismo caso

Se separan con comas:

$canCancel = match ($status) {
    'pending', 'paid'      => true,
    'shipped', 'delivered' => false,
};

6. Condiciones con match (true)

Para rangos o condiciones, el truco es comparar con true: gana el primer caso que se cumpla.

$discount = match (true) {
    $total >= 100 => 20,
    $total >= 50  => 10,
    default       => 0,
};

El orden importa: si pusieras primero $total >= 50, un total de 150 se quedaría con el 10 %.

Cuándo sigue siendo mejor switch

Cada caso de match es una sola expresión. Si en cada caso tienes que hacer varias cosas, switch se lee mejor:

switch ($event) {
    case 'order_paid':
        $this->mailer->sendReceipt($order);
        $this->stock->reserve($order);
        $this->logger->info('Order paid');
        break;
    case 'order_cancelled':
        $this->stock->release($order);
        $this->mailer->sendCancellation($order);
        break;
}

Con match tendrías que meter cada bloque en una función aparte. A veces es buena idea, pero no siempre compensa.

El resumen

switch match
Devuelve un valor No Sí
Comparación == ===
Necesita break Sí No
Si no encaja nada No hace nada Lanza un error
Varias líneas por caso Sí No

La regla: si estás eligiendo un valor, match; si estás eligiendo qué hacer, switch.

Y ya está

La próxima vez que escribas un switch que solo asigna una variable en cada caso, pásalo a match: será más corto, no tendrá break que olvidar y te avisará del caso que falte. Y si te pica la curiosidad por otros atajos del lenguaje, mira los operadores que casi nadie usa.

← Volver al blog

Mi hija de 11 años me ayudó a crear el diseño de este portfolio.