switch and match are structures that select an alternative among several possible cases.
When you have to make a decision based on a single variable but with many possible options (for example: “If the code is 200, do this; if it’s 404, do that; if it’s 500…”), if/elseif becomes very messy.
Historically, the solution was switch. But today we have something better: match.
Let’s look at the battle and why we have a clear winner.
The old classic: switch
You’ve probably seen it a thousand times. It works, but it has three serious problems that constantly cause bugs:
- Loose Comparison:
switchuses==. If you compare the number0with the string"0", it will say they are equal. This is dangerous. - Forgetting
break: If you forget to addbreak, PHP will continue executing the next case (fallthrough). - It’s a “Statement”, not an “Expression”: It doesn’t return a value. You have to assign the variable inside each case.
// The old style (Prone to errors)
$status = '200'; // Note: It's a string
$message = '';
switch ($status) {
case 200: // Matches because '200' == 200!
$message = 'OK';
break; // What a pain to write this every time!
case 404:
$message = 'Not found';
break;
default:
$message = 'Unknown error';
}The new standard: match (PHP 8)
match solves all the previous problems in one fell swoop.
- Strict Comparison: Uses
===. The type matters. - No
break: Only executes the matching branch and exits. Impossible to get it wrong. - It’s an “Expression”: Returns a value directly, so you can assign it to a variable.
Look how clean it is compared to the previous one:
$status = 200;
$message = match ($status) {
200 => 'OK',
404 => 'Not found',
500, 503 => 'Server error', // We can group cases with commas
default => 'Unknown error',
};Key differences: why match is superior
Let’s break it down so there are no doubts left.
| Feature | switch (Old) | match (Modern) |
|---|---|---|
| Comparison | Loose (==). Dangerous. | Strict (===). Safe. |
| Result | Returns nothing. | Returns a value. |
| Syntax | Verbose (case, break, ;). | Concise (=>, ,). |
| Fallthrough | Yes (needs break). | No (one match and exit). |
| Errors | If no default, does nothing. | If no match, throws UnhandledMatchError. |
The nuance of loose comparison in switch
switch uses non-strict comparison. Since PHP 8, a non-numeric string is no longer automatically converted to a number, but numeric strings can still match integers:
$payment = "200"; // A numeric string
switch ($payment) {
case 200:
echo "Payment accepted"; // Matches because "200" == 200
break;
}With match, this wouldn’t happen because "200" !== 200. Still, the input must be validated before making a business decision.
Advanced patterns with match
match is very powerful. It not only compares exact values, you can also use dynamic expressions.
$age = 25;
$category = match (true) {
$age >= 65 => 'Retired',
$age >= 18 => 'Adult',
default => 'Minor',
};By doing match (true), it looks for the first condition that is true. It is a very elegant way to replace long chains of if/elseif.
When should I use switch?
Honestly… almost never.
The only reason to use switch today is if you need the “fallthrough” behavior (executing several cases in a row without break), but it’s such a rare and discouraged practice that you probably won’t need it.