The match Expression

PHP 8's match is a sharper, safer cousin of switch : it returns a value, compares strictly, never falls through, and fails loudly on the unexpected. This lesson shows when to reach for it — and the elegant match(true) trick for ranges.

Learn The match Expression in our free PHP course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.

Part of the free Php course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

What You'll Learn in This Lesson

1️⃣ The Basics

match takes a subject and a set of arms written value => result . It returns the result of the first arm whose value matches, and because it's an expression , you can assign or echo that result directly. One arm can list several comma-separated values.

2️⃣ Strict Matching (=== not ==)

The headline safety feature: match compares with strict === , whereas switch uses loose == . So a string "1" will not match an integer 1 arm — exactly the type-juggling surprise that switch lets slip through.

3️⃣ No Fall-Through, No break

In a switch , forgetting break makes execution "fall through" into the next case — a perennial source of bugs. match arms are self-contained: exactly one runs, and there's no break to forget.

4️⃣ match(true) for Ranges

Here's the trick that makes match shine. Use match (true) and make each arm a boolean condition ; the first one that's true wins. A long if/elseif ladder collapses into a clean, readable table — perfect for grades, price bands, and thresholds.

5️⃣ The No-Match Case

If nothing matches and there's no default , match throws an UnhandledMatchError . That's a feature : unexpected values fail loudly during testing instead of slipping by. Add a default arm when you want a catch-all, or omit it when you want every case handled explicitly.

Now you try. Fill the ___ blanks to map an HTTP method to an action.

These scrambled lines should map a status code to a label and print it. Put them in the order that prints Status: Not Found .

Define the subject $code first, then open the match , list the arms (each ending in a comma, including default ), close it with ;'} , and finally echo the result. Because match is an expression, the closing ;'} ends the assignment statement. Output: Status: Not Found .

Predict the output before revealing each answer.

Prints str . match uses strict === , so the string "1" does not match the integer 1 arm — it matches the "1" arm.

Throws an UnhandledMatchError . This is deliberate — unexpected values fail loudly rather than passing silently.

Returns C . The first arm ( $n >= 90 ) is false; the second ( $n >= 70 ) is the first true arm, so it wins.

📋 Quick Reference — match vs switch

Write it yourself, run it on onecompiler.com/php or your own machine, then check against the expected output in the comments.

Practice quiz

What does this print? echo match("1") { 1 => "int", "1" => "str", default => "def" };

  • int
  • def
  • str
  • UnhandledMatchError

Answer: str. match compares with strict ===, so the string "1" does not equal the integer 1 arm — it matches the "1" arm and prints str.

Which comparison operator does the match expression use?

  • === (strict)
  • == (loose)
  • <=> (spaceship)
  • It depends on the values

Answer: === (strict). match always uses strict === comparison, unlike switch which uses loose ==. This avoids type-juggling surprises.

What happens when no arm matches and there is no default arm?

  • Returns null
  • Returns false
  • Silently does nothing
  • Throws UnhandledMatchError

Answer: Throws UnhandledMatchError. An unmatched match with no default throws an UnhandledMatchError — a feature, so unexpected values fail loudly.

With $n = 75, what does match(true) { $n >= 90 => "A", $n >= 70 => "C", default => "F" } return?

  • A
  • C
  • F
  • It throws an error

Answer: C. In match(true) the first arm that evaluates to true wins. $n >= 90 is false, $n >= 70 is the first true arm, so it returns C.

Is match a statement or an expression?

  • An expression that returns a value
  • A statement, like switch
  • Neither — it is a loop
  • A function call

Answer: An expression that returns a value. match is an expression: it evaluates to a single value you can assign or echo directly.

Do match arms fall through like switch cases, requiring break?

  • Yes, you need break in each arm
  • Only the default arm falls through
  • No — exactly one arm runs and there is no break
  • Only if you omit default

Answer: No — exactly one arm runs and there is no break. match has no fall-through. Each arm is self-contained, exactly one runs, and there is no break to forget.

How do you make one match arm handle several subject values?

  • Stack them like case labels
  • List them comma-separated: 301, 302 => "Redirect"
  • Use the || operator
  • You cannot — one value per arm

Answer: List them comma-separated: 301, 302 => "Redirect". An arm can list several comma-separated values, e.g. 301, 302 => "Redirect".

Why does switch matching "1" against case 1 succeed where match would not?

  • switch sorts its cases first
  • switch caches results
  • switch only compares strings
  • switch uses loose == comparison

Answer: switch uses loose == comparison. switch uses loose ==, so "1" == 1 is true. match uses strict ===, so the string would not hit an integer arm.

Can a single match arm run multiple statements?

  • Yes, separate them with semicolons
  • No — an arm returns a single expression
  • Yes, wrap them in braces
  • Only inside the default arm

Answer: No — an arm returns a single expression. match arms return a single expression. For multiple statements, call a function from the arm or use switch/if.

What is the idiomatic use of match(true)?

  • To always return the default
  • To loop over an array
  • To replace if/elseif ladders for ranges and conditions
  • To compare two booleans

Answer: To replace if/elseif ladders for ranges and conditions. match(true) makes each arm a boolean condition; the first true arm wins — perfect for grades, price bands, and thresholds.