PHP switch vs match

Compare switch statements with PHP 8 match expressions and choose clear, predictable branching.

Lesson 31 of 86Beginner9 min read

Both switch and match choose behavior from several possible values. Their similarity can hide important differences. switch is a statement that uses loose comparison and can continue into following cases. match, available since PHP 8.0, is an expression that uses strict comparison, produces a value, and selects one result without fall-through.

This guide uses delivery methods and numeric-looking strings to make those differences visible. You will learn how to write a complete branch, what happens when no case matches, and why replacing switch with match requires checking your input types. Neither form automatically validates a request field; the comparison policy must fit the application rule.

How a switch statement works

A switch evaluates its subject and compares it against case values using PHP's loose comparison rules. After finding a matching case, execution begins there. It continues through subsequent statements until a break, return, exception or the end of the switch stops it. Forgetting break is therefore a common cause of unexpected extra work.

Fall-through can be intentional. Several case labels can share one block, or one case can perform a setup step before entering the next block. Make that intention explicit with a comment. If every case simply assigns one result, a match expression may express the operation more clearly in PHP 8 code.

A default block handles values that do not match any case. Without one, the switch may finish without doing anything. If code after the switch assumes a variable was assigned in a case, an unknown input can leave that variable undefined. Initialize it deliberately or handle all possible inputs with a default that returns or throws.

How a match expression works

match compares the subject with each arm using strict identity, the same comparison policy as ===. The value and type must match. An integer one and the string '1' are different. Only the selected result expression runs, and the whole match expression produces that result. Assign it to a variable or return it directly.

Arms use => and commas instead of case, colons and break. Several conditions can precede one result, such as 'courier', 'express' => 12. A default arm handles remaining values. If no arm matches and no default exists, PHP throws UnhandledMatchError. This is useful when an unexpected value represents a broken assumption rather than an acceptable fallback.

An arm produces one expression, not a free-standing sequence of statements. Call a named function when a selected operation needs several steps, or use an ordinary conditional statement. A compact match containing large closures or hidden side effects can be less readable than a longer switch.

Ranges and ordered conditions

A value map is the most natural use of match: one status produces one label, one command selects one handler, or one extension selects a known format. For ranges, an if sequence often reads better. PHP also permits match (true) with boolean conditions, which selects the first condition strictly equal to true.

When conditions overlap, their order matters. A condition for amounts above one hundred must come before a broader condition for amounts above twenty if the larger tier should win. Write the thresholds as explicit rules and test the boundaries. A match expression is still ordered logic; it does not infer which condition is most specific.

Keep validation separate from mapping. Reject unknown delivery options before charging a fee, or make the default arm throw a clear exception. A broad default can hide newly added enum cases or spelling mistakes. An exhaustive map without a default can instead surface an unsupported value immediately, provided the caller handles that error appropriately.

PHP switch vs match Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Assign a delivery fee with switch

The break after pickup stops execution before the standard case. Removing it would assign five even though pickup matched first. This example's default treats every unknown method as an expensive delivery method, which is a demonstration policy rather than a recommended checkout rule. A real checkout should usually reject an unrecognized method.

PHP
<?php
$method = 'pickup';
switch ($method) {
    case 'pickup':
        $fee = 0;
        break;
    case 'standard':
        $fee = 5;
        break;
    default:
        $fee = 12;
}
echo $fee . PHP_EOL;
Output
0
Example 2

Observe the strict type difference

An HTML form commonly supplies string values, so a numeric-looking selection may take the string arm. A switch using case 1 can match that same string loosely. Before migrating code, decide whether the application wants exact typed input or validated conversion. Changing syntax without reviewing data types can change behavior.

PHP
<?php
$input = '1';
$label = match ($input) {
    1 => 'integer one',
    '1' => 'string one',
    default => 'other',
};
echo $label . PHP_EOL;
Output
string one

Common PHP switch vs match Mistakes

Assuming the forms are interchangeable

Do not carry break statements into match arms, and do not omit them from switch just because match does not need them. Do not expect an unknown match input to silently return null. Also avoid loose switch comparisons when confusing strings and numbers could select the wrong operation.

The official PHP match reference documents its PHP 8.0 introduction, strict comparison and exhaustive behavior. For older supported runtimes, use an explicit switch or if structure. During migration, test integer values, numeric strings, null and unexpected values when those are possible at the boundary.

PHP switch vs match in Real Projects

Practical task: map approved shipping methods

Write a function returning a fee in integer units for pickup, standard and express delivery. Unknown methods must raise an exception rather than quietly selecting a price. Use a match expression because each approved method maps to one value. The task assumes the method string has already been extracted safely from a request.

PHP
<?php
function shippingFee(string $method): int {
    return match ($method) {
        'pickup' => 0,
        'standard' => 5,
        'express' => 12,
        default => throw new InvalidArgumentException('Unknown delivery method'),
    };
}
echo shippingFee('standard') . PHP_EOL;
echo shippingFee('express') . PHP_EOL;
Output
5
12

The exception makes the invalid-input rule visible. Try the spelling 'Standard' and explain why it fails: matching is case sensitive and strict. If your product accepts case-insensitive names, normalize approved input before calling the function and document that policy. Never normalize unrelated fields merely because one field allows it.

PHP switch vs match FAQ

Does match replace every switch?

No. Match is particularly good at producing a single value. A statement-oriented branch with several visible actions can remain a switch or become a clear if sequence.

Can two match values share a result?

Yes. Put them before the same arrow separated by commas. There is no fall-through into the next arm.

What happens without a default?

A switch may do nothing. A match throws UnhandledMatchError when no arm matches. Decide which behavior expresses the requirement.

Why did a migration change my form handling?

Form values are commonly strings. Switch's loose comparison can accept a string for an integer case, while match requires the exact type.

Can a match arm throw?

Yes in PHP 8. Throw is an expression, which allows an invalid-input default to fail clearly.

PHP switch vs match Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Multiple choiceeasy

A switch case assigns a fee and should stop before the next case. What is normally needed?

PHP switch vs match Quiz

2 questions to check what you learned.

  1. Which comparison does match use?

    • Strict identity, including type
    • Loose equality only
    • Alphabetical ordering
  2. What happens when no match arm matches and there is no default?

    • Null is always returned
    • UnhandledMatchError is thrown
    • The final arm runs