

PHP 8.0: Match Expressions
source link: https://php.watch/versions/8.0/match-expression
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Match expression syntax is one of the nicest features in PHP 8 that improves the switch
syntax in multiple ways.
$status = match($request_method) { 'post' => $this->handlePost(), 'get', 'head' => $this->handleGet(), default => throw new \Exception('Unsupported'), };
Functionality from the match
expression above, compared to a switch
block:
- switch ($request_method) { + $status = match($request_method) { - case 'post': - $status = $this->handlePost(); - break; + 'post' => $this->handlePost(), - case 'get': - case 'head': - $status = $this->handleGet(); - break; + 'get', 'head' => $this->handleGet(), - default: - throw new \Exception('Unsupported'); + default => throw new \Exception('Unsupported'), - } + };
match
expressions can return a value
The return value of the expression used in each "arm" (similar to each case
in switch
blocks) is can be assigned to a variable.
$name = match(2) { 1 => 'One', 2 => 'Two', }; echo $name; // "Two"
It is not necessary to assign the return value to anything, the return value of the matched arm will be returned from the match
expression.
Multiple matching conditions allowed
It is possible for a match
expression to contain one or more matching conditions, and they will behave similar to multiple cascading case
keys in a switch
block.
match($request_method) { 'post' => $this->handlePost(), 'get', 'head' => $this->handleGet(), };
$request_method === 'get'
and $request_method === 'head'
both conditions will be handled with $this->handleGet()
.
Each matching case must only contain one expression
Unlike switch
blocks that can contain any number of expressions, a match
arm can only contain only one expression.
match($name) { 'foo' => initFoo(); processFoo(); };
Syntax above is not allowed . Each arm must contain only a single expression.
Implicit break
Each matched "arm" of a match
expression only allows a single expression, and it will not fall-through, as it does in a switch
block.
switch ('test') { case 'test': $this->sendTestAlert(); case 'send': $this->sendNuclearAlert(); }
It is easy to overlook the missing break
call in each of the switch
case
, which allows the code to fall-through to the next case. In the switch
block above, missing break;
statement makes the code fall-through and execute $this->sendNuclearAlert()
as well, although it is unlikely the outcome you expect.
match ('test') { 'test' => $this->sendTestAlert(), 'send' => $this->sendNuclearAlert(), };
match
expressions work without explicit break
statements. It only executes one matching arm, and immediately returns the value, making it imply a break
call right after the expression the matched arm executes.
default
case
match
statement supports a default
arm that will work similar to the default
case in switch
blocks.
A default
arm will catch all expressions if none of the other conditions matched.
match ('Qux') { 'foo' => ..., 'bar' => ..., default => echo 'Unknown: ' . $name, }; // "Unknown: Qux"
match
expression MUST match a condition
switch
blocks silently proceeds the code flow if there are no matching case
keys. match
expressions do not.
In a match
expression, there must
be condition that matches the expression, or a default
case to handle it. If there are no matches, match
expression throws an \UnhandledMatchError
exception.
$value = 3; match($value) { 1 => 'One', 2 => 'Two', };
match
expression above throws error:
Fatal error: Uncaught UnhandledMatchError in ...
UnhandledMatchError
exception
match
expressions throw an \UnhandledMatchError
exception if there are no matches in within the expression.
\UnhandledMatchError
is a new exception class in PHP 8, and it extends \Error
. For a full hierarchy of all PHP core exception classes, including the ones added in PHP 8, see Hierarchy of PHP exceptions
This class can be easily poly-filled:
class UnhandledMatchError extends \Error {}
Strict matches without type coercion
One of the most important design choices in match
expression is that it matches without type coercion.
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"
In a typical switch
block, its cases are matched loosely, i.e with ==
. In match
expressions, all matching arms are matched with strict comparison ( ===
), leaving possible bugs in switch
blocks out.
In the snippet above, each individual arm will be matched for the value and type.
Match against arbitrary expressions
match
expression allows a given value to be matched against an expression.
match($foo){ 404 => 'Page not found', Response::REDIRECT => 'Redirect', $client->getCode() => 'Client Error', $response->getCode() => 'Response Error', default => 'Unknown error' };
The expressions will be evaluated in the order they are laid out.
match
expression will try to match $foo
against in this order:
$foo === 404 $foo === Response::REDIRECT $foo === $client->getCode() $foo === $response->getCode() default
If it finds a positive match, the rest of the code will not be evaluated.
match
vs switch
switch
match
Requires PHP ^8.0
No
Yes
No
Yes
default
condition support
Yes
Yes
Multiple conditions in single arm
Yes
Yes
Multiple expressions in code block
Yes
No
No
Yes
Falls-through without break
Yes
No
Throws an exception on no matches
No
Yes
Match against arbitrary expressions
Yes
Yes
Strict type-safe comparison
No
Yes
Backwards compatibility impact
match
expressions are a new syntax in PHP 8. Code that uses match
expressions will not work in older PHP versions.
The \UnhandledMatchError
exception class can be.
Trying to run code that uses this expression will fail with a parse error in older PHP versions:
Parse error: syntax error, unexpected '=>' (T_DOUBLE_ARROW) in ... on line ...
Recommend
-
32
PHP RFC: Allow function calls in constant expressions
-
18
PHP RFC: Match expression Date: 2020-04-12 Autho...
-
21
PHP RFC: Match expression v2 Da...
-
28
上个月下旬PHP社区发布是PHP8第一个,正式版本也将于今年年底发布。PHP8带来来那个两个最令人激动的特性:JIT和match表达式。 本文我...
-
18
« back — written by Brent on July 08, 2020 PHP 8: match or switch? ...
-
3
Writing better Regular Expressions in PHP Published On2021-05-26 ...
-
5
New issue Don't lint match expressions with cfged arms #8443
-
6
PHP Tricks: Uncommon match() expressions Submitted by Larry on 15 April 2022 - 1:15p...
-
7
PHP Tricks: Multi-value match() Submitted by Larry on 19 April 2022 - 11:41am...
-
5
December 5, 2023 How to use Regular Expressions and Match Evaluators in .NET
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK