DEV3 Technologies home

DEV3 Developer Forum

What is the difference between match and switch in PHP 8 and when should I use enums?

PHP helpSolved0 views
dev3 ·

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?

#php#php-8#enums

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 string or int and 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 match for mapping; keep switch only for multi-statement branches.
0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.