Php match vs switch

PHP 8: match or switch?

PHP 8 introduces the new match expression. A powerful feature that will often be the better choice to using switch . So what exactly are the differences?

Let’s start by comparing the two. Here’s a classic switch example:

switch ($statusCode) < case 200: case 300: $message = null; break; case 400: $message = 'not found'; break; case 500: $message = 'server error'; break; default: $message = 'unknown status code'; break; >

Here’s its match equivalent:

$message = match ($statusCode) < 200, 300 => null, 400 => 'not found', 500 => 'server error', default => 'unknown status code', >;

First of all, the match expression is significantly shorter:

  • it doesn’t require a break statement
  • it can combine different arms into one using a comma
  • it returns a value, so you only have to assign value once

That’s already quite a lot, but there’s even more to it!

# No type coercion

match will do strict type checks instead of loose ones. It’s like using === instead of == . People will probably disagree whether that’s a good thing or not, but that’s a topic on its own.

$statusCode = '200'; $message = match ($statusCode) < 200 => null, default => 'unknown status code', >; // $message = 'unknown status code'

Noticed a tpyo? You can submit a PR to fix it. If you want to stay up to date about what’s happening on this blog, you can follow me on Twitter or subscribe to my newsletter:

Читайте также:  Первое пересечение двух множеств python

# Unknown values cause errors

If you forget to check for a value, and when there’s no default arm specified, PHP will throw an UnhandledMatchError exception. Again more strictness, but it will prevent subtle bugs from going unnoticed.

$statusCode = 400; $message = match ($statusCode) < 200 => 'perfect', >; // UnhandledMatchError

# Only single-line expressions, for now

Just like short closures, you can only write one expression. Expression blocks will probably get added at one point, but it’s still not clear when exactly.

# Combining conditions

You already noticed the lack of break ? This also means match doesn’t allow for fallthrough conditions, like the two combined case lines in the first switch example. On the other hand though, you can combine conditions on the same line, separated by commas.

So you have the same functionality as switch in this regards, but with less writing, and less ways to screw up. Win-win!

$message = match ($statusCode) < 200, 300, 301, 302 => 'combined expressions', >;

# Complex conditions and performance

During the RFC discussion, some people suggested the following pattern as an argument against adding the match expression:

$message = [ $this->matchesRegex($line) => 'match A', $this->matchesOtherRegex($line) => 'match B', ][$line] ?? 'no match';

There’s one big caveat though: this technique will execute all regex functions first, decreasing performance. A good argument for match .

# Throwing exceptions

Finally, because of throw expressions in PHP 8, it’s also possible to directly throw from an arm, if you’d like to.

$message = match ($statusCode) < 200 => null, 500 => throw new ServerError(), default => 'unknown status code', >;

# Pattern matching

Ok, there’s one more thing: pattern matching. It’s a technique used in other programming languages, to allow complexer matching than simple values. Think of it as regex, but for variables instead of text.

Pattern matching isn’t supported right now, because it’s quite a complex feature, but Ilija Tovilo, the RFC author did mention it as a possible future feature. Something to look out for!

PHP in 2023

Interface Default Methods

# So, switch or match?

If I’d need to summarise the match expression in one sentence, I’d say it’s the stricter and more modern version of it’s little switch brother.

There are some cases — see what I did there? — where switch will offer more flexibility, especially with multiline code blocks. However, the strictness of the match operator is appealing, and the perspective of pattern matching would be a game-changer for PHP.

I admit I never wrote a switch statement in the past years because of its many quirks; quirks that match actually solve. So while it’s not perfect yet, there are use cases that I can think of, where match would be a good… match.

Источник

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

Как использовать выражение 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 все ветви кода, соответствующие условию, подлежат строгому сравнению (===) . Это защищает разработчиков от ошибок.

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

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

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.

Источник

Оцените статью