PHP 8: Modern PHP Development · Object-Oriented PHP 8

Enums

Use pure and backed enums to replace magic strings and class constants.

Enums (8.1) define a closed set of possible values. Pure enums have only cases; backed enums map each case to an int or string for storage and serialization, with from() (throws on invalid value) and tryFrom() (returns null). Enums can implement interfaces, have methods and constants, and work perfectly with match. Use them for statuses, roles and other finite sets instead of string constants.

<?php
enum OrderStatus: string
{
    case Pending = 'pending';
    case Paid = 'paid';
    case Shipped = 'shipped';
    case Cancelled = 'cancelled';

    public function label(): string
    {
        return match ($this) {
            self::Pending => 'Awaiting payment',
            self::Paid => 'Paid',
            self::Shipped => 'On its way',
            self::Cancelled => 'Cancelled',
        };
    }

    public function canTransitionTo(self $next): bool
    {
        return in_array($next, match ($this) {
            self::Pending => [self::Paid, self::Cancelled],
            self::Paid => [self::Shipped, self::Cancelled],
            default => [],
        }, true);
    }
}

$status = OrderStatus::from($row['status']);   // from DB
$maybe  = OrderStatus::tryFrom($_GET['status'] ?? '') ?? OrderStatus::Pending;
echo json_encode(['status' => $status]);       // {"status":"paid"}

Common pitfalls

  • Using from() on untrusted input without handling ValueError — use tryFrom().
  • Comparing enum cases to strings ($status === 'paid') — compare to cases.
  • Enums cannot have state (properties); keep data in other objects.

Key points

  • Enums model closed sets of values
  • Backed enums serialize to int/string
  • Enums can have methods and implement interfaces

Further reading: PHP manual: enumerations

Practice questions

What's the difference between from() and tryFrom()?

Answer

Both convert a scalar to a backed enum case. from() throws a ValueError for unknown values; tryFrom() returns null, which suits untrusted input.

Why are enums better than class constants for statuses?

Answer

Enums are a real type, so function ship(OrderStatus $s) can't receive an arbitrary string; they're exhaustively checkable with match and can carry behavior (labels, allowed transitions).

Open in the app to mark lessons complete, take notes and track your progress.