match ($value) { ... } compara un valor con una lista de ramas usando el === estricto y devuelve el resultado de la primera rama que coincide. Varios valores pueden compartir una rama, default recoge el resto y, si nada coincide, PHP lanza un UnhandledMatchError.
Fíjate en el punto y coma tras la llave de cierre: match es una expresión, como 1 + 2, así que todo el bloque es una sola sentencia de asignación. Cada rama es values => result, separadas por comas, y se permite una coma final tras la última rama.
Varios valores en una rama
Enumera los valores separados por comas. La rama coincide si el sujeto es idéntico (===) a cualquiera de ellos.
Devolver match directamente desde una función, como aquí, es la forma más común de usarlo.
match vs switch
La misma correspondencia escrita de las dos formas, con una entrada que muestra la mayor diferencia: la comparación. switch usa ==, así que la cadena "1" coincide con case 1. match usa ===, así que no.
match | switch | |
|---|---|---|
| Comparación | estricta === | flexible == |
| Resultado | devuelve un valor | sentencia, no devuelve nada |
| Fallthrough | nunca | sí, hasta break |
| Varios valores | 1, 2 => | case 1: case 2: apilados |
| Sin coincidencia | lanza UnhandledMatchError | no hace nada |
| Cuerpo de una rama | una expresión | cualquier número de sentencias |
Usa match cuando conviertes un valor en otro. Quédate con switch cuando una rama necesita varias sentencias o cuando el fallthrough es lo que buscas; la página de switch tiene los dos casos.
UnhandledMatchError: cuando ninguna rama coincide
Sin una rama default, un valor que no coincide con nada es un error, no un null silencioso. Es una ventaja: un código de estado nuevo o una errata fallan de forma visible en lugar de colarse.
PHP se detiene con PHP Fatal error: Uncaught UnhandledMatchError: Unhandled match case of type string. Una configuración de desarrollo (con zend.exception_ignore_args desactivado) nombra el valor: Unhandled match case 'XL'. Corrígelo añadiendo default => 'other', o capturando el error donde se espera un valor desconocido:
match(true) para rangos y condiciones
match compara el sujeto con cada rama, así que si el sujeto es true, cada rama puede ser una condición. Gana la primera condición que se evalúe exactamente a true.
Dos detalles de ese bloque. throw es una expresión desde PHP 8, así que puede ser el resultado de una rama. Y como la comparación es estricta, cada condición debe devolver un booleano real: una rama como $name => ... nunca coincide con true aunque $name sea una cadena no vacía. Solo se evalúa la rama que coincide, así que el throw solo se ejecuta con una edad negativa.
match con enums
match y los enums encajan bien: dentro de un método del enum, match ($this) asigna un valor a cada caso. Consulta enums en PHP para los propios enums.
Aquí no hay default a propósito. Si alguien añade un quinto caso más adelante, llamar a color() con él lanza un error en lugar de devolver un color equivocado.
Varias sentencias en una rama
Una rama contiene una sola expresión, así que 'save' => { ...; ... } no es PHP válido. Lleva el trabajo a una función y llámala desde la rama. Las funciones de las ramas que no coinciden nunca se llaman.
Cambia $format a 'json' o 'xml' y vuelve a ejecutarlo.
Preguntas frecuentes
¿Cuál es la diferencia entre match y switch en PHP?
match compara con el === estricto, devuelve un valor, nunca pasa a la rama siguiente, acepta varios valores separados por comas en cada rama y lanza un UnhandledMatchError cuando ninguna rama coincide. switch compara con el == flexible, es una sentencia que no devuelve nada, sigue hacia abajo sin break y no hace nada en silencio cuando ningún case coincide.
¿Qué pasa cuando ninguna rama coincide en una expresión match de PHP?
PHP lanza un UnhandledMatchError. Añade una rama default => ... para cualquier otro valor, o captura el error con try { ... } catch (\UnhandledMatchError $e) { ... }.
¿Cómo uso match con condiciones como mayor que en PHP?
Compara con true: match (true) { $age < 13 => 'child', $age < 18 => 'teen', default => 'adult' }. Cada rama es una condición, y gana la primera que sea exactamente true.
¿Puede una rama de match ejecutar varias sentencias en PHP?
No, cada rama es una sola expresión. Pon las sentencias en una función o un método y llámalo desde la rama, por ejemplo 'export' => exportCsv($rows).
¿Qué versión de PHP añadió match?
PHP 8.0. En PHP 7 la misma lógica necesita una sentencia switch o una búsqueda en un array como $labels[$status] ?? 'Unknown'.