match

(PHP 8)

La expresión match ramifica la evaluación basada en una comprobación de identidad de un valor. De forma similar a una sentencia switch, una expresión match tiene una expresión de sujeto que se compara con múltiples alternativas. A diferencia de switch, se evaluará a un valor muy parecido al de las expresiones ternarias. A diferencia de switch, la comparación es una comprobación de identidad (===) en lugar de una comprobación de igualdad débil (==). Las expresiones match están disponibles a partir de PHP 8.0.0.

Ejemplo #1 Estructura de una expresión match

<?php
$return_value
= match (subject_expression) {
single_conditional_expression => return_expression,
conditional_expression1, conditional_expression2 => return_expression,
};
?>

Ejemplo #2 Ejemplo básico de uso de match

<?php
$comida
= 'pastel';

$valor_devuelto = match ($comida) {
'manzana' => 'Esta comida es una manzana',
'barra' => 'Esta comida es una barra',
'pastel' => 'Esta comida es un pastel',
};

var_dump($valor_devuelto);
?>

El resultado del ejemplo sería:

string(24) "Esta comida es un pastel"

Ejemplo #3 Ejemplo de uso de match con operadores de comparación

<?php
$age
= 18;

$output = match (true) {
$age < 2 => 'Eres un bebé',
$age < 10 => 'Eres un niño',
$age < 18 => 'Eres un adolescente',
$age >= 18 => 'Eres mayor de edad',
$age < 40 => 'Eres un adulto joven',
$age >= 40 => 'Eres un adulto viejo'
};

var_dump($output);
?>

El resultado del ejemplo sería:

string(18) "Eres mayor de edad"

Nota: El resultado de una expresión match no necesita ser utilizado.

Nota: Una expresión match debe terminar con un punto y coma ;.

La expresión match es similar a una sentencia switch pero tiene algunas diferencias clave:

  • Un brazo de match compara los valores estrictamente (===) en lugar de hacerlo de forma suelta como lo hace la sentencia switch.
  • Una expresión match retorna un valor.
  • Los brazos de Match no pasan a casos posteriores como lo hacen las sentencias switch.
  • Una expresión match debe ser completa.

Como las expresiones switch, las expresiones match se ejecutan de brazo a brazo. Al principio, no se ejecuta ningún código. Las expresiones condicionales sólo se evalúan si todas las anteriores no coinciden con la expresión del sujeto. Sólo se evaluará la expresión de retorno correspondiente a la expresión condicional que coincida. Por ejemplo:

<?php
$result
= match ($x) {
foo() => ...,
$this->bar() => ..., // bar() no se llama si foo() === $x
$this->baz => beep(), // beep() no se llama a menos que $x === $this->baz
// etc.
};
?>

Los brazos de la expresión match pueden contener varias expresiones separadas por una coma. Se trata de un OR lógico, y es una abreviatura de múltiples brazos match con el mismo lado derecho.

<?php
$result
= match ($x) {
// Este brazo match:
$a, $b, $c => 5,
// Es equivalente a estos tres:
$a => 5,
$b => 5,
$c => 5,
};
?>

Un caso especial es el patrón default. Este patrón permite hacer coincidir cualquier cosa que no se haya hecho coincidir previamente. Por ejemplo:

<?php
$expressionResult
= match ($condition) {
1, 2 => foo(),
3, 4 => bar(),
default =>
baz(),
};
?>

Nota: Múltiples patrones default lanzarán un error E_FATAL_ERROR.

Una expresión match debe ser completa. Si la expresión del sujeto no es manejada por ningún brazo match se lanza un UnhandledMatchError.

Ejemplo #4 Ejemplo de una expresión match no controlada

<?php
$condition
= 5;

try {
match (
$condition) {
1, 2 => foo(),
3, 4 => bar(),
};
} catch (
\UnhandledMatchError $e) {
var_dump($e);
}
?>

El resultado del ejemplo sería:

object(UnhandledMatchError)#1 (7) {
  ["message":protected]=>
  string(33) "Unhandled match value of type int"
  ["string":"Error":private]=>
  string(0) ""
  ["code":protected]=>
  int(0)
  ["file":protected]=>
  string(9) "/in/ICgGK"
  ["line":protected]=>
  int(6)
  ["trace":"Error":private]=>
  array(0) {
  }
  ["previous":"Error":private]=>
  NULL
}

Usando expresiones match para manejar comprobaciones de no identidad

Es posible utilizar un expresión match para manejar casos de condicionales de no identidad usando true como expresión del sujeto.

Ejemplo #5 Uso de expresiones match generalizadas para ramificar en rangos de integers

<?php

$age
= 23;

$result = match (true) {
$age >= 65 => 'senior',
$age >= 25 => 'adult',
$age >= 18 => 'young adult',
default =>
'kid',
};

var_dump($result);
?>

El resultado del ejemplo sería:

string(11) "young adult"

Ejemplo #6 Uso de expresiones match generalizadas para ramificar el contenido de strings.

<?php

$text
= 'Bienvenue chez nous';

$result = match (true) {
str_contains($text, 'Welcome') || str_contains($text, 'Hello') => 'en',
str_contains($text, 'Bienvenue') || str_contains($text, 'Bonjour') => 'fr',
// ...
};

var_dump($result);
?>

El resultado del ejemplo sería:

string(2) "fr"