Lesson 42 of 100
Control flow15 min5 checksPHP 8.5

Return Values with match Expressions

Learn how PHP 8.4 match expressions return values, compare strictly, avoid fallthrough, and need a default arm or exhaustive cases.

01 · THE IDEAREAD → TRY → LEARN

Why match exists

A match expression chooses one result from several alternatives. It looks a little like switch, but it behaves more like a compact, safer lookup. The whole construct evaluates to a value, so you can assign it, return it, or pass it straight to echo.

The basic shape is a subject in parentheses followed by arms. Each arm has one or more conditions, then =>, then the expression to return. Use a comma to list several conditions that share one result. A standalone match ends with a semicolon, as does an assignment or return that uses it.

Strict comparison

The most important rule is that match compares with identity (===), not loose equality (==). The integer 1 and the string '1' are different subjects. That removes a whole class of surprises that switch can produce when values of different types compare as equal.

Example
<?php
$code = '1';
$label = match ($code) {
    1 => 'integer one',
    '1' => 'string one',
    default => 'other',
};
echo $label, "\n";
Output
string one

The subject is the string '1', so only the second arm matches. The default arm catches anything not matched earlier. Only the chosen result expression runs, and there is no fallthrough, so you never need break.

Being exhaustive

A match must handle every subject it can receive. If no arm matches and there is no default, PHP throws UnhandledMatchError. This is intentional: a forgotten case becomes a visible failure instead of a silent null.

Example
<?php
$value = 5;
try {
    echo match ($value) {
        1, 2 => 'low',
        3, 4 => 'mid',
    }, "\n";
} catch (UnhandledMatchError $e) {
    echo $e->getMessage(), "\n";
}
Output
Unhandled match case 5

Choose deliberately between the two designs. Add default when unexpected input should produce a fallback result. Omit it when unexpected input is a bug that should be loud.

Matching conditions with true

Because arms are compared strictly with the subject, you can use true as the subject and write boolean conditions in the arms. PHP tests the arms from top to bottom and stops at the first one that evaluates to exactly true. This is useful for ranges.

Example
<?php
function gradeBand(int $score): string
{
    return match (true) {
        $score >= 90 => 'A',
        $score >= 80 => 'B',
        $score >= 70 => 'C',
        default => 'review',
    };
}

echo json_encode([gradeBand(95), gradeBand(80), gradeBand(12)], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["A","B","review"]

Order matters here. A score of 95 satisfies all three comparisons, but the first arm wins. Put the most specific or highest threshold first. Each condition must be a real boolean expression; a merely truthy value such as 1 would not match true strictly.

Worked reasoning

In gradeBand(80), PHP checks 80 >= 90, which is false, so it moves on. Next 80 >= 80 is true, so the result is 'B' and the later arms are never evaluated. For 12, every comparison fails and default returns 'review'.

This lazy evaluation also applies to the conditions themselves. If an arm contains a function call, it is not made when an earlier arm has already matched.

Common mistakes

  • Expecting loose matching, such as treating '404' like 404.
  • Forgetting default when the input comes from outside your code.
  • Using match (true) with conditions in the wrong order.
  • Putting statements in an arm. Each result must be a single expression.
  • Forgetting the semicolon after the closing brace.

Exercise contract

Write statusLabel($code): string. It receives a JSON value and returns one of four labels, using strict matching:

  • 200 returns success.
  • 404 returns not-found.
  • 500 or 503 returns server-error.
  • Anything else returns unknown. This includes numeric strings such as "404" and null.

Return the label rather than printing it. The tests compare the returned strings, including the case where a string looks like a valid integer.

Recap

match returns a value, compares with ===, never falls through, and throws UnhandledMatchError when nothing matches. Use commas to share a result, default for a fallback, and match (true) for ordered range checks.

Before you start

Functions · Arrays · Types

You’ll practice
  • Use exhaustive strict matching with a fallback
  • Implement and test a deterministic PHP 8.4 function
Your task

Make statusLabel() pass all 5 checks. Run your code as often as you like, then check your answer.

exercise.phpSaved in this browserPHP 8.5
CONSOLE & CHECKS● Ready

Ready when you are

Your output will appear here.
Make it work. Then make it pass.

PHP loads on your first run. Each check starts fresh. Your code stays in this browser; clearing site data removes your progress. A check or the task looks wrong? Report a problem with this exercise.