Весенние скидки до 30 000 ₽
На все профессии до 31 марта
Главная | Все статьи | Код

Как использовать выражение match в PHP и чем оно отличается от switch

PHP Время чтения статьи ~6 минут
Как использовать выражение match в PHP и чем оно отличается от switch главное изображение

Выражение match разветвляет поток исполнения кода в PHP. Но практически тем же занимается и оператор switch. Разбираемся, чем они отличаются друг от друга и в каких случаях лучше применять именно match.

Эта статья больше подходит для тех, кто уже немного знает основы PHP. Если вы еще не разобрались с ним, советуем перед прочтением пройти большую профессию по PHP на Хекслете.

Выражение match разветвляет поток исполнения кода через проверку совпадения значения с заданным условием. Как и оператор switch, match принимает на вход выражение, которое сравнивается с множеством альтернатив. Только в отличие от switch, оно возвращает значение, похожее на тернарный оператор.

Выражение match появилось в восьмой версии PHP. Оно выполняет практически те же задачи, что и switch, но имеет ряд преимуществ.

Рассмотрим пример использования выражения match:

$subject = 'two';

echo match ($subject) {
    'one' => 'foo',
    'two' => 'bar',
    'three' => 'baz',
    default => 'default',
}; // => bar

Если заменить в этом примере match на блок switch, код будет длиннее:

$subject = 'two';

switch ($subject) {
    case 'one':
        $result = 'foo';
        break;
    case 'two':
        $result = 'bar';
        break;
    case 'three':
        $result = 'baz';
        break;
    default:
        $result = 'default';
        break;
}

echo $result; // => bar

Давайте более подробно поговорим о том, как работает выражение match.

Возврат значения

В отличие от switch, выражение match возвращает результат — возвращаемое значение каждой ветви можно сохранить в переменной. Как и в случае с секциями case в блоках switch.

$name = match(2) {
    1 => 'One',
    2 => 'Two',
};

echo $name; // => Two

Множественные условия

Для выражения match можно задать несколько условий, указав их через запятую. Тогда выражение будет похоже на каскад секций case в блоке switch.

match($case) {
    'one' => 'fizz',
    'two', 'three' => 'bazz',
};

Для условий $case === 'two' или $case === 'three' будет возвращено значение ’bazz’.

Однострочные выражения

В отличие от блоков switch, которые содержат произвольное количество выражений, в каждой ветви match есть только одно выражение. Поэтому так делать нельзя:

match($name) {
    'foo' => 
        initFoo();
        processFoo();
};

Отсутствие оператора break

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

А чтобы при использовании switch не забыть о ключевом слове break, PHP продолжает исполнять команды следующей секции case:

switch ('test') {
    case 'test':
        sendTestAlert();
    case 'send':
        sendNuclearAlert();
}

Здесь мы пропустили оператор break. В результате сквозного исполнения кода выполняется и функция sendNuclearAlert(), хотя этого не должно было произойти.

Для выражения match не требуется ключевое слово break. Оно выполняет одну ветвь, возвращает значение и останавливается:

match ('test') {
    'test' => sendTestAlert(),
    'send' => sendNuclearAlert(),
};

Читайте также: «Комьюнити у PHP сейчас одно из самых активных»: интервью c разработчиком Yii Framework Александром Макаровым

Шаблон default

Для выражения match можно задать шаблон default, аналогично похожей конструкции в блоке switch.

Ветвь default совпадает со всеми условиями, которым не нашлось других совпадений.

match ('Qux') {
    'foo' => ...,
    'bar' => ...,
    default => echo 'Unknown: ' . $name,
};

// => Unknown: Qux

Отсутствие совпадений

Если блок switch не обнаруживает совпадения, то PHP продолжает выполнять код. Выражение match носит исчерпывающий характер. Если совпадения не найдены, и нет конструкции default, выражение выдает исключение \UnhandledMatchError.

$value = 3;
match($value) {
    1 => 'One',
    2 => 'Two',
};

Если ввести такое выражение match, получим ошибку:

Fatal error: Uncaught UnhandledMatchError in ...

Исключение UnhandledMatchError

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

Это подвид \Error, новый класс исключений в PHP 8. Почитать о структуре базовых исключений PHP, включая новые классы, можно в этой статье.

Добавить эту функциональность в предыдущие версии PHP можно с помощью полифилла:

class UnhandledMatchError extends \Error {}

Строгое сравнение без приведения типов

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

function read(mixed $key): string {
    return match ($key) {
        1 => 'Integer 1',
        '1' => 'String 1',
        true => 'Bool true',
        [] => 'Empty array',
        [1] => 'Array [1]',
    };
}

read(1); // "Integer 1"
read('1'); // "String 1"
read(true); // "Bool true"

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

В примере выше каждая ветвь проверяется на предмет соответствия значения и типа.

Читайте также: Как работать с базами данных в PHP с помощью модуля PDO

Сравнение с произвольными выражениями

match позволяет сравнить значение с выражением.

match($foo){
    404 => 'Page not found',
    Response::REDIRECT => 'Redirect',
    $client->getCode() => 'Client Error',
    $response->getCode() => 'Response Error',
    default => 'Unknown error'
};

Здесь match ищет совпадение для $foo в следующем порядке:

  1. $foo === 404
  2. $foo === Response::REDIRECT
  3. $foo === $client->getCode()
  4. $foo === $response->getCode()
  5. default

Проверка кода завершится, как только будет обнаружено совпадение.

Чем различаются match и switch

С какими версиями PHP совместим match

Код с выражением match работает только в PHP версии 8.0 и новее. Для более ранних версий можно бэкпортировать класс исключений \UnhandledMatchError.

Если выполнить код с выражением match в предыдущих версиях PHP, возникнет ошибка анализа:

Parse error: syntax error, unexpected '=>' (T_DOUBLE_ARROW) in ... on line ...

Что выбрать: match или switch

Итак, выражение match — это более строгая и современная альтернатива для оператора switch.

В некоторых случаях switch более универсален, особенно если нужно использовать многострочные блоки кода. Но у этого оператора много недостатков, которые исправлены в match. В целом match выигрывает благодаря точности и более широким возможностям сопоставления с переданным значением.

Станьте профессиональным PHP-разработчиком с нуля за 10 месяцев На Хекслете есть профессия «PHP-разработчик». Пройдите ее, чтобы изучить один из самых известных языков программирования, освоить популярные фреймворки и создать большое портфолио с проектами на GitHub.

Стать PHP-разработчиком

Рекомендуемые программы
профессия
от 6 300 ₽ в месяц
Разработка фронтенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 4 апреля
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Django
10 месяцев
с нуля
Старт 4 апреля
профессия
от 6 183 ₽ в месяц
Ручное тестирование веб-приложений
4 месяца
с нуля
Старт 4 апреля
профессия
от 6 300 ₽ в месяц
Разработка приложений на языке Java
10 месяцев
с нуля
Старт 4 апреля
профессия
от 5 025 ₽ в месяц
новый
Сбор, анализ и интерпретация данных
9 месяцев
с нуля
Старт 4 апреля
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Laravel
10 месяцев
с нуля
Старт 4 апреля
профессия
от 5 840 ₽ в месяц
Создание веб-приложений со скоростью света
5 месяцев
c опытом
Старт 4 апреля
профессия
от 9 900 ₽ в месяц
Разработка фронтенд- и бэкенд-компонентов для веб-приложений
16 месяцев
с нуля
Старт 4 апреля
профессия
от 6 300 ₽ в месяц
Разработка бэкенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 4 апреля
профессия
новый
Автоматизированное тестирование веб-приложений на JavaScript
8 месяцев
c опытом
в разработке
Старт 4 апреля
профессия
Верстка с использованием последних стандартов CSS
5 месяцев
с нуля
Старт в любое время