switch y match son estructuras que seleccionan una alternativa entre varios casos posibles.
Cuando tienes que tomar una decisión basada en una sola variable pero con muchas opciones posibles (por ejemplo: “Si el código es 200, haz esto; si es 404, haz esto otro; si es 500…”), el if/elseif se vuelve muy sucio.
Históricamente, la solución era switch. Pero hoy tenemos algo mejor: match.
Veamos la batalla y por qué tenemos un claro ganador.
El viejo conocido: switch
Seguro que lo has visto mil veces. Funciona, pero tiene tres problemas graves que causan bugs constantemente:
- Comparación Débil:
switchusa==. Si comparas el número0con la cadena"0", dirá que son iguales. Esto es peligroso. - El olvido del
break: Si se te olvida ponerbreak, PHP seguirá ejecutando el siguiente caso (fallthrough). - Es una “Sentencia”, no una “Expresión”: No devuelve un valor. Tienes que asignar la variable dentro de cada caso.
// El estilo antiguo (Propenso a errores)
$estado = '200'; // Nota: Es un string
$mensaje = '';
switch ($estado) {
case 200: // ¡Coincide porque '200' == 200!
$mensaje = 'OK';
break; // ¡Qué pesadez escribir esto siempre!
case 404:
$mensaje = 'No encontrado';
break;
default:
$mensaje = 'Error desconocido';
}El nuevo estándar: match (PHP 8)
match soluciona todos los problemas anteriores de un plumazo.
- Comparación Estricta: Usa
===. El tipo importa. - Sin
break: Solo ejecuta la rama que coincide y sale. Imposible equivocarse. - Es una “Expresión”: Devuelve un valor directamente, por lo que puedes asignarlo a una variable.
Mira qué limpieza comparado con el anterior:
$estado = 200;
$mensaje = match ($estado) {
200 => 'OK',
404 => 'No encontrado',
500, 503 => 'Error de servidor', // Podemos agrupar casos con comas
default => 'Error desconocido',
};Diferencias clave: ¿por qué match es superior?
Vamos a desglosarlo para que no queden dudas.
| Característica | switch (Antiguo) | match (Moderno) |
|---|---|---|
| Comparación | Débil (==). Peligroso. | Estricta (===). Seguro. |
| Resultado | No devuelve nada. | Devuelve un valor. |
| Sintaxis | Verbosa (case, break, ;). | Concisa (=>, ,). |
| Fallthrough | Sí (necesita break). | No (una coincidencia y sale). |
| Errores | Si no hay default, no hace nada. | Si no hay coincidencia, lanza UnhandledMatchError. |
El matiz de la comparación débil en switch
switch usa comparación no estricta. Desde PHP 8, una cadena no numérica ya no se convierte automáticamente a número, pero las cadenas numéricas aún pueden coincidir con enteros:
$pago = "200"; // Una cadena numérica
switch ($pago) {
case 200:
echo "Pago aceptado"; // Coincide porque "200" == 200
break;
}Con match, esto no ocurriría porque "200" !== 200. Aun así, la entrada debe validarse antes de tomar una decisión de negocio.
Patrones avanzados con match
match es muy potente. No solo compara valores exactos, también puedes usar expresiones dinámicas.
$edad = 25;
$categoria = match (true) {
$edad >= 65 => 'Jubilado',
$edad >= 18 => 'Adulto',
default => 'Menor',
};Al hacer match (true), busca la primera condición que sea verdadera. Es una forma muy elegante de sustituir cadenas largas de if/elseif.
¿Cuándo debo usar switch?
Sinceramente… casi nunca.
La única razón para usar switch hoy en día es si necesitas el comportamiento de “fallthrough” (ejecutar varios casos seguidos sin break), pero es una práctica tan rara y desaconsejada que probablemente no la necesites.