La expresión match de PHP 8 es una alternativa mejorada a switch con tres diferencias clave: usa comparación estricta (===), no tiene fall-through implícito entre casos y devuelve un valor directamente. También lanza UnhandledMatchError si ningún caso coincide, lo que evita errores silenciosos.
match vs switch: diferencias básicas
<?php
$codigo = 200;
// Con switch: comparación débil, fall-through, no devuelve valor
switch ($codigo) {
case 200:
$msg = 'OK';
break;
case 404:
$msg = 'No encontrado';
break;
default:
$msg = 'Desconocido';
}
// Con match: comparación estricta, devuelve valor directamente
$mensaje = match ($codigo) {
200 => 'OK',
301, 302 => 'Redirección',
404 => 'No encontrado',
500 => 'Error del servidor',
default => 'Código desconocido',
};
echo $mensaje; // OK
?>
Comparación estricta: la gran diferencia con switch
<?php
$valor = '0';
// switch con comparación débil: '0' == false es true en PHP
switch ($valor) {
case false:
echo 'switch: falsy'; // ? esto se ejecuta (¡incorrecto!)
break;
case '0':
echo 'switch: cero';
break;
}
// match con comparación estricta: '0' !== false
$resultado = match ($valor) {
false => 'match: falsy',
'0' => 'match: cero', // ? esto se ejecuta (correcto)
default => 'otro',
};
echo $resultado; // match: cero
?>
UnhandledMatchError: sin silencio cuando no hay caso
<?php
function descripcionMetodo(string $metodo): string
{
return match ($metodo) {
'GET' => 'Obtener recurso',
'POST' => 'Crear recurso',
'PUT' => 'Reemplazar recurso',
'PATCH' => 'Modificar parcialmente',
'DELETE' => 'Eliminar recurso',
};
// Si $metodo es 'OPTIONS' u otro valor no listado,
// lanza UnhandledMatchError automáticamente
}
try {
echo descripcionMetodo('OPTIONS');
} catch (UnhandledMatchError $e) {
echo 'Método HTTP no reconocido';
}
?>
Ejemplos reales: roles y permisos
<?php
enum Rol: string
{
case Admin = 'admin';
case Editor = 'editor';
case Lector = 'lector';
}
function nivelAcceso(Rol $rol): int
{
return match ($rol) {
Rol::Admin => 3,
Rol::Editor => 2,
Rol::Lector => 1,
};
}
echo nivelAcceso(Rol::Editor); // 2
?>
Rangos y condiciones en match (PHP 8.0+)
<?php
function categoriaPrecio(float $precio): string
{
return match (true) {
$precio < 10 => 'Muy barato',
$precio < 50 => 'Económico',
$precio < 200 => 'Precio medio',
$precio < 1000 => 'Premium',
default => 'Lujo',
};
}
echo categoriaPrecio(7.5); // Muy barato
echo categoriaPrecio(89.0); // Precio medio
echo categoriaPrecio(2500.0); // Lujo
?>
match para tipos MIME
<?php
function extensionDesdeContentType(string $contentType): string
{
return match ($contentType) {
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/webp' => 'webp',
'application/pdf' => 'pdf',
'text/plain' => 'txt',
'application/json' => 'json',
'application/octet-stream' => 'bin',
default => 'dat',
};
}
echo extensionDesdeContentType('image/png'); // png
echo extensionDesdeContentType('text/plain'); // txt
?>
La documentación oficial de match en PHP detalla la precedencia de los brazos del match, la combinación de múltiples condiciones por caso y cómo se comporta con no-arms y el default.
