I keep seeing match expressions and enums in PHP 8 code. How do they differ from switch statements and class constants, and what is a clean example for order statuses?
DEV3 Developer Forum
What is the difference between match and switch in PHP 8 and when should I use enums?
Ask a question
Every post is reviewed first. Usually reviewed within 24 hours.
dev3 ·
0
1 reply
dev3 · Accepted answer
switch is a statement using loose comparison and fall-through (you must remember break). match (PHP 8.0) is an expression, uses strict comparison (===), has no fall-through, and throws UnhandledMatchError if no arm matches.
$label = match ($status) {
'pending', 'processing' => 'In progress',
'shipped' => 'On the way',
'delivered' => 'Done',
default => 'Unknown',
};
Because it returns a value you can assign or return it directly. A common trick to match conditions:
$size = match (true) {
$kb < 100 => 'small',
$kb < 1000 => 'medium',
default => 'large',
};
Enums (PHP 8.1) replace groups of string/int constants with a real type, so invalid values cannot exist.
enum OrderStatus: string
{
case Pending = 'pending';
case Shipped = 'shipped';
case Delivered = 'delivered';
public function label(): string
{
return match ($this) {
self::Pending => 'Waiting for payment',
self::Shipped => 'On the way',
self::Delivered => 'Delivered',
};
}
public function isFinal(): bool
{
return $this === self::Delivered;
}
}
$s = OrderStatus::from('shipped'); // throws ValueError if invalid
$t = OrderStatus::tryFrom('bogus'); // null
echo $s->value; // 'shipped'
function ship(OrderStatus $s): void {} // type safe
OrderStatus::cases(); // all cases, handy for select boxes
match over an enum without default is exhaustive: if you add a case and forget to handle it, you get an error instead of silent wrong behaviour. PHP does not check at compile time, so test it or use PHPStan.
Pitfalls
- Backed enums need
stringorintand every case needs a unique value. - Enums cannot hold state or be instantiated with
new; they can implement interfaces and have constants and static methods. - JSON encodes a backed enum as its value; for databases store
->value(Laravel and Doctrine have enum casts). - Use
matchfor mapping; keepswitchonly for multi-statement branches.
0