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.