← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

match Expression (PHP 8.0)

PHP PHP 8.0+ Beginner
debt(d3/e3/b3/t7)
d3 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'default linter catches the common case' (d3). The term's detection_hints list rector and phpcs, both of which can detect switch blocks that should be replaced with match (code_pattern: switch\s*\() and flag missing default arms. This is standard linter/fixer territory, not requiring a specialist SAST tool.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix describes replacing switch blocks with match expressions, adding default arms, and converting fall-through groups to comma-separated patterns. This is a mechanical but non-trivial refactor within individual components — not a one-liner, but not cross-cutting either. Rector can automate much of it.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Match applies to web, cli, and queue-worker contexts, giving it moderate reach. However, the burden is localised: each switch-to-match conversion is a self-contained change and the choice doesn't impose a persistent productivity tax on unrelated parts of the codebase.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field explicitly states: 'match is just syntactic sugar for switch' — but it uses strict === comparison (no type coercion), returns a value, throws UnhandledMatchError on no match, and has no fall-through. These are multiple significant behavioural differences from switch, contradicting how a nearly identical construct (switch) works in PHP and most other languages. A developer migrating switch logic to match without knowing these differences can introduce silent type-strictness bugs or unexpected exceptions.

About DEBT scoring →

TL;DR

PHP 8.0's match is a stricter switch — uses strict (===) comparison, each arm is an expression (not statements), returns a value, and throws UnhandledMatchError if no arm matches.

Explanation

match($x) { pattern => value, ... } differences from switch: strict comparison (===, no coercion), each arm is a single expression (no statements, no break needed), match returns a value (expression, not statement), no fall-through (comma-separated patterns for multiple matches), throws UnhandledMatchError with no match and no default. Multiple patterns per arm: 1, 2 => 'low'. Combining with null coalescing: $result = match(true) { $a > 0 => 'positive', default => 'zero or negative' }. Works with enums (PHP 8.1): match($status) { Status::Active => ... }.

Common Misconception

match is just syntactic sugar for switch — match uses strict comparison (no type coercion), returns values, throws on no match, and has no fall-through.

Why It Matters

match replaces switch for value-returning contexts and eliminates switch's type coercion bugs — a safer, more expressive alternative.

Common Mistakes

  • Forgetting default arm — throws UnhandledMatchError.
  • Trying multi-statement arms — each arm is one expression.
  • Not knowing match uses === — helps avoid type coercion bugs common in switch.

Code Examples

✗ Vulnerable
switch ($status) {
    case 'active': $label = 'Active'; break;
    case 'inactive': $label = 'Inactive'; break;
    default: $label = 'Unknown';
}
✓ Fixed
$label = match($status) {
    'active'   => 'Active',
    'inactive' => 'Inactive',
    default    => throw new InvalidArgumentException("Unknown: $status")
};

// Multiple patterns:
$type = match($code) {
    200, 201, 202 => 'success',
    400, 422      => 'client error',
    500, 503      => 'server error',
};

Added 23 Mar 2026
Views 44
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 1 ping W 1 ping T 0 pings F 2 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 1 ping M 1 ping T 2 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 1 ping T 0 pings W
No pings yet today
PetalBot 1
Amazonbot 6 SEMrush 5 Google 4 Scrapy 4 Unknown AI 3 Perplexity 3 Ahrefs 3 Bing 2 ChatGPT 1 Claude 1 Meta AI 1 Sogou 1 PetalBot 1
crawler 32 crawler_json 2 pre-tracking 1
DEV INTEL Tools & Severity
🔵 Info ⚙ Fix effort: Low
⚡ Quick Fix
Replace switch blocks that return values with match expressions. Always add default arm. Use comma-separated patterns for multiple matches.
📦 Applies To
PHP 8.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
switch\s*\(
Auto-detectable: ✓ Yes rector phpcs
🤖 AI Agent
Confidence: Medium False Positives: Medium ✓ Auto-fixable Fix: Low Context: Function


✓ schema.org compliant