match

(PHP 8)

Выражение match предназначено для ветвления потока исполнения на основании проверки совпадения значения с заданным условием. Аналогично оператору switch, выражение match принимает на вход выражение, которое сравнивается с множеством альтернатив. Но, в отличии от switch, оно обрабатывает значение в стиле, больше похожем на тернарный оператор. Также, в отличии от switch, используется строгое сравнение (===), а не слабое (==). Выражение match доступно начиная с PHP 8.0.0.

Пример #1 Структура выражения match

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

Замечание: Результат match использовать не обязательно.

Замечание: Выражение match должно завершаться точкой с запятой ;.

Выражение match похоже на оператор switch за исключением некоторых ключевых отличий:

  • В отличии от switch, в match используется строгое сравнение (===).
  • Выражение match возвращает результат.
  • В Match исполняется только одна, первая подошедшая, ветвь кода, тогда как в switch происходит сквозное исполнение начиная с подошедшего условия и до первого встретившегося оператора break.
  • Выражение match должно быть исчерпывающим.

Также как и оператор switch, match последовательно проводит проверки на совпадение с заданными условиями. Выполнения кода условий происходит лениво, т.е. код следующего условия выполняется только если все предыдущие проверки провалились. И выполнено будет только одна ветвь кода, соответствующая подошедшему условию. пример:

<?php
$result 
match ($x) {
    
foo() => ...,
    
$this->bar() => ..., // bar() не будет выполнен, если foo() === $x
    
$this->baz => beep(), // beep() будет выполнен только если $x === $this->baz
    // etc.
};
?>

Условия в match могут быть множественными. В этом случае их следует разделять запятыми. Множественные условия работают по принципу логического ИЛИ и, по сути, являются сокращённой формой для случаев, когда несколько условий должны обрабатываться идентично.

<?php
$result 
match ($x) {
    
// Множественное условие:
    
$a$b$c => 5,
    
// Аналогично трём одиночным:
    
$a => 5,
    
$b => 5,
    
$c => 5,
};
?>

Также можно использовать шаблон default. Этот шаблон совпадает с чем угодно, для чего не нашлось совпадений раньше. К примеру:

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

Замечание: Использование нескольких шаблонов default приведет к фатальной ошибке E_FATAL_ERROR.

Выражение match должно быть исчерпывающим. Если проверяемое выражение не совпало ни с одним из условий, то будет выброшено исключение UnhandledMatchError.

Пример #2 Пример не обрабтанного выраженияо

<?php
$condition 
5;

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

Результат выполнения данного примера:

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
}

Использование match для проверки сложных условий

Выражение match можно использовать не только для проверки идентичности, но и для любых выражений возвращающих логическое значение. В этом случае в качестве входного параметра передаётся выражение true.

Пример #3 Использование match для ветвления в зависимости от вхождения в диапазоны целых чисел

<?php

$age 
23;

$result match (true) {
    
$age >= 65 => 'пожилой',
    
$age >= 25 => 'взрослый',
    
$age >= 18 => 'совершеннолетний',
    default => 
'ребёнок',
};

var_dump($result);
?>

Результат выполнения данного примера:

string(11) "совершеннолетний"

Пример #4 Использование match для ветвления в зависимости от содержимого строки

<?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);
?>

Результат выполнения данного примера:

string(2) "fr"