The match expression is one of those PHP features that instantly makes your code cleaner once you start using it.
It was introduced in PHP 8.0, and while it’s been around for a few years, many developers still underuse it — especially those newer to PHP.
This quick guide will show you:
- what
matchis - why it’s better than
switchin many cases - and how to use it in real-world scenarios
At its core, match lets you compare a value against multiple conditions and return a result.
It looks similar to switch, but there are two critical differences:
✅ Key advantages over switch:
- Uses strict comparison (
===) - Returns a value (no need for manual
return) - No
breakstatements required - More concise and predictable
Real-World Example: Driver Resolver
Let’s say you’re building a Git integration layer.
❌ Traditional approach (if / elseif / else):
public function driver(string $driver): RepositoryDriver
{
if ($driver === 'github') {
return new GitHubDriver();
} elseif ($driver === 'gitlab') {
return new GitLabDriver();
} elseif ($driver === 'bitbucket') {
return new BitbucketDriver();
} else {
throw new \InvalidArgumentException("Unsupported driver: $driver");
}
}
✅ Using match:
public function driver(string $driver): RepositoryDriver
{
return match ($driver) {
'github' => new GitHubDriver(),
'gitlab' => new GitLabDriver(),
'bitbucket' => new BitbucketDriver(),
default => throw new \InvalidArgumentException("Unsupported driver: $driver"),
};
}
Why this is better:
- Single return point
- Less boilerplate
- Easier to scan visually
- Safer due to strict comparison
Multiple Conditions per Branch
You can group conditions — super useful in real systems.
return match ($driver) {
'github', 'self-hosted' => new GitHubDriver(),
'gitlab' => new GitLabDriver(),
'bitbucket' => new BitbucketDriver(),
default => throw new \InvalidArgumentException("Unsupported driver: $driver"),
};
👉 Perfect for:
- aliases
- fallback drivers
- shared implementations
Advanced Trick: match (true)
This is where things get interesting.
Instead of matching values, you match conditions:
$message = match (true) {
$user->isAdmin() => 'User is an admin',
$user->isEditor() => 'User is an editor',
$user->isSubscriber() => 'User is a subscriber',
default => 'User role is unknown',
};
Why use this?
- Cleaner alternative to multiple
ifstatements - Keeps logic declarative
- Easier to extend
Match + Enums = 🔥
match really shines when combined with enums.
enum JobType: string
{
case WebDeveloper = 'web_developer';
case Designer = 'designer';
case ProjectManager = 'project_manager';
case SalesManager = 'sales_manager';
public function toFriendly(): string
{
return match ($this) {
self::WebDeveloper => 'Web Developer',
self::Designer => 'Designer',
self::ProjectManager => 'Project Manager',
self::SalesManager => 'Sales Manager',
};
}
}
Why this combo is powerful:
- Fully type-safe
- No need for
defaultif exhaustive - Centralized mapping logic
- Extremely maintainable
When NOT to Use match
Despite how great it is, match isn’t always the right tool.
Avoid it when:
- You need complex logic blocks (not just expressions)
- You’re mutating state across branches
- Conditions become too dynamic or procedural
The match expression is one of those features that:
- reduces bugs
- improves readability
- and makes your intent obvious
Once you start using it, going back to switch feels… outdated.
If you’re writing modern PHP — especially with enums — match should absolutely be part of your toolkit.
