php-switch-y-match-en-php

Switch and match in PHP

  • 3 min

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:

  1. Loose Comparison: switch uses ==. If you compare the number 0 with the string "0", it will say they are equal. This is dangerous.
  2. Forgetting break: If you forget to add break, PHP will continue executing the next case (fallthrough).
  3. 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';
}
Copied!

The new standard: match (PHP 8)

match solves all the previous problems in one fell swoop.

  1. Strict Comparison: Uses ===. The type matters.
  2. No break: Only executes the matching branch and exits. Impossible to get it wrong.
  3. 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',
};
Copied!

Key differences: why match is superior

Let’s break it down so there are no doubts left.

Featureswitch (Old)match (Modern)
ComparisonLoose (==). Dangerous.Strict (===). Safe.
ResultReturns nothing.Returns a value.
SyntaxVerbose (case, break, ;).Concise (=>, ,).
FallthroughYes (needs break).No (one match and exit).
ErrorsIf 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;
}
Copied!

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',
};
Copied!

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.