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:
matchis an expression, whileswitchis a statement;matchmust be terminated by a semi-colon (;), however, same is not required forswitch;- A
matcharm can have multiple expressions (separated by a comma); they're evaluated in the same way as a logical OR. However, aswitchcasemay only have a single expression; - In
match, you can only have single-line expressions that return a value when amatcharm matches. Inswitch, however, eachcasecan have multiple statements (i.e. a block of statements) that are executed if thecasematches.
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.