match

(PHP 8)

A expressão match ramifica a avaliação baseada em uma verificação de identidade de um valor. Semelhante a uma declaração switch, uma expressão match possui uma expressão sujeito que é comparada com múltiplas alternativas. Ao contrário da switch, ela irá avaliar para um valor assim como as expressões ternárias. Diferente da switch, a comparação é uma verificação de identidade (===) em vez de uma comparação de equalidade fraca (==). Expressões match estão diponíveis a partir do PHP 8.0.0.

Exemplo #1 Estrutura de uma expressão match

<?php
$valor_de_retorno
= match (expressao_sujeito) {
expressao_condicional_unica => expressao_de_retorno,
expressao_condicional1, expressao_condicional2 => expressao_de_retorno,
};
?>

Exemplo #2 Basic match usage

<?php
$comida
= 'bolo';

$valor_de_retorno = match ($comida) {
'apple' => 'Essa comida é uma maçã',
'bar' => 'Essa comida é um bar',
'bolo' => 'Essa comida é um bolo',
};

var_dump($valor_de_retorno);
?>

O exemplo acima produzirá:

 string(19) "Essa comida é um bolo" 

Nota: O resultado de uma expressão match não precisa ser usado.

Nota: Uma expressão matchdeve ser terminada por um ponto e vírgula ;.

A expressão match é similar a uma declaração switch mas tem algumas diferenças importantes:

  • Um braço match compara valores estritamente (===) em vez de frouxamente como a declaração switch faz.
  • Uma expressão match retorna um valor.
  • Braços match não seguem para casos posteriores da maneira que declarações switch seguem.
  • Uma expressão match deve ser exaustiva.

Assim como as declarações switch, expressões match são executadas braço de correspondência por braço de correspondência. No início, nenhum código é executado. A expressões condicionais só são avaliadas se todas as expressões condicionais anteriores não corresponderem à expressão sujeito. Apenas a expressão de retorno pertencente à expressão condicional de correspondência será avaliada.

<?php
$resultado
= match ($x) {
foo() => ...,
$this->bar() => ..., // $this->bar() não é chamado se foo() === $x
$this->baz => beep(), // beep() não é chamado a não ser que $x === $this->baz

Braços da expressão match podem conter múltiplas expressões separadas por uma vírgula. Isso é um OR lógico, e é uma forma abreviada para múltimplos braços de correspondência com o mesmo lado direito.

<?php
$resultado
= match ($x) {
// Este braço de correspondência:
$a, $b, $c => 5,
// É equivalente a estes três braços de correspondência:
$a => 5,
$b => 5,
$c => 5,
};
?>

Um caso especial é o padrão default. Esse padrão atende a qualquer coisa que não tenha sido atendida anteriormente. Por exemplo:

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

Nota: Múltiplos padrões default irão emitir um erro E_FATAL_ERROR.

Uma expressão match deve ser exaustiva. Se a expressão sujeito não for tratada por nenhum braço de correspondência um UnhandledMatchError é lançado.

Exemplo #3 Exemplo de uma expressão match não tratada

<?php
$condicao
= 5;

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

O exemplo acima produzirá:

 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 expressões match para tratar verificações sem identidade

É possível usar uma expressão match para tratar casos condicionais sem identidade usando true como a expressão sujeito.

Exemplo #4 Usando uma expressão match generalizada para ramificar com base em intervalos de inteiros

<?php

$idade
= 23;

$resultado = match (true) {
$idade >= 65 => 'senhor',
$idade >= 25 => 'adulto',
$idade >= 18 => 'adolescente',
default =>
'criança',
};

var_dump($resultado);
?>

O exemplo acima produzirá:

 string(11) "adolescente" 

Exemplo #5 Usando uma expressão match generalizada para ramificar com base no conteúdo de strings

<?php

$texto
= 'Bienvenue chez nous';

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

var_dump($resultado);
?>

O exemplo acima produzirá:

 string(2) "fr" 
To Top