match
expressions were introduced in PHP 8 while switch
statement have existed since PHP 4. They both differ in terms of the following:
Syntactical Differences
A switch
statement has the following syntax:
switch (subject) { case expr: // execute block of statements break; // or continue or return default: // execute block of statements break; // or continue or return }
In switch
, the continue
statement acts similar to break
. It can be useful if, for example, you have a switch
inside a loop and wish to continue
to the next iteration of the outer loop (in which case, you would use continue 2
for example).
A match
expression has the following syntax:
$result = match (subject) { expr1, expr2 => value, default => value, };
Essentially, match
and switch
have the following syntactical differences:
match
is an expression, whileswitch
is a statement;match
must be terminated by a semi-colon (;
), however, same is not required forswitch
;- A
match
arm can have multiple expressions (separated by a comma); they're evaluated in the same way as a logical OR. However, aswitch
case
may only have a single expression; - In
match
, you can only have single-line expressions that return a value when amatch
arm matches. Inswitch
, however, eachcase
can have multiple statements (i.e. a block of statements) that are executed if thecase
matches.
Return Value
The match
expression evaluates to a value which can be stored in a variable or returned. For example:
// PHP 8+ $subject = 'two'; $result = match ($subject) { 'one' => 'foo', 'two' => 'bar', 'three' => 'baz', default => 'default', }; echo $result; // 'bar'
// PHP 8+ $subject = 'two'; echo match ($subject) { 'one' => 'foo', 'two' => 'bar', 'three' => 'baz', default => 'default', }; // 'bar'
The switch
statement on the other hand, does not evaluate to a value itself, but rather executes a different piece of code depending on the case
it matches. For example:
// PHP 4+ $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'
You may use return
inside a case
block to return a value if the switch
is used inside a function
. For example:
function getValue(string $subject) { switch ($subject) { case 'one': return 'foo'; case 'two': return 'bar'; default: return 'baz'; } } echo getValue('one'); // 'foo' echo getValue('two'); // 'bar' echo getValue('non-existent'); // 'baz'
Comparison Strictness
In a switch
statement, comparisons are made based on loose/weak equality (==
). For example:
switch (8.0) { case '8.0': $result = 'not expected'; break; case 8.0: $result = 'expected'; break; } echo $result; // 'not expected'
In a match
expression, comparisons are made based on strict equality (===
). For example:
echo match (8.0) { '8.0' => 'not expected', 8.0 => 'expected', }; // 'expected'
Handling of No Match
When there's no match found, and a default
does not exist, the match
expression throws an UnhandledMatchError
. For example:
// PHP 8+ $subject = 'no-match'; $result = match ($subject) { 'one' => 'foo', 'two' => 'bar', }; // Fatal error: Uncaught UnhandledMatchError
A switch
on the other hand, does nothing when there's no matching case
and a default
is not present. For example:
// PHP 4+ $subject = 'no-match'; switch ($subject) { case 'one': echo 'foo'; break; case 'two': echo 'bar'; break; }
Fall-Through
switch
continues to execute the statements until the end of the switch
block (i.e. they fall-through) till a terminating statement (such as break
, continue
or return
) is found. For example:
// PHP 4+ $subject = 'two'; switch ($subject) { case 'one': echo 'one;'; case 'two': echo 'two;'; case 'three': echo 'three;'; default: echo 'default;'; } // output: 'two;three;default;'
In the following example, after the match is found at case 'two'
, the execution falls-through till case 'three'
and stops (as it has a break
statement):
// PHP 4+ $subject = 'two'; switch ($subject) { case 'one': echo 'one;'; case 'two': echo 'two;'; case 'three': echo 'three;'; break; default: echo 'default;'; } // output: 'two;three;'
This is not the case with match
arms, however, as they do not fall-through like that. In a match
expression, if there's a match, the remaining conditions are not evaluated. For example:
// PHP 8+ $subject = 'two'; $result = match ($subject) { 'one' => 'one;', 'two' => 'two;', 'three' => 'three;', default => 'default;', }; echo $result; // 'two;'
This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.