Type-Safe Status Management with PHP 8.1+ Backed Enums

📖 2 minutes read

PHP 8.1’s backed enums are perfect for managing database statuses with compile-time safety. Unlike magic strings, enums provide IDE autocomplete, prevent typos, and centralize status logic.

Why It Matters

In production applications, hardcoded strings for statuses like 'pending' or 'in_progress' are prone to typos and difficult to refactor. Backed enums solve this by providing a single source of truth for all possible states.

Implementation

enum OrderStatus: string
{
    case PENDING = 'pending';
    case PROCESSING = 'processing';
    case COMPLETED = 'completed';
    case CANCELED = 'canceled';
    case ON_HOLD = 'on_hold';
    
    public function getLabel(): string
    {
        return match($this) {
            self::PENDING => 'Awaiting Review',
            self::PROCESSING => 'In Progress',
            self::COMPLETED => 'Successfully Completed',
            self::CANCELED => 'Order Canceled',
            self::ON_HOLD => 'Paused',
        };
    }
    
    public static function toArray(): array
    {
        return collect(self::cases())
            ->mapWithKeys(fn($status) => [
                $status->value => $status->getLabel()
            ])
            ->toArray();
    }
    
    public function canTransitionTo(self $newStatus): bool
    {
        return match($this) {
            self::PENDING => in_array($newStatus, [self::PROCESSING, self::CANCELED, self::ON_HOLD]),
            self::PROCESSING => in_array($newStatus, [self::COMPLETED, self::CANCELED]),
            self::ON_HOLD => in_array($newStatus, [self::PROCESSING, self::CANCELED]),
            default => false,
        };
    }
}

Integrating with Eloquent

Laravel makes it incredibly easy to use enums by casting the database value directly to the enum class.

class Order extends Model
{
    protected $casts = [
        'status' => OrderStatus::class,
    ];
}

// Usage
$order->status = OrderStatus::COMPLETED;  // Type-safe!
$order->status->getLabel();  // "Successfully Completed"
OrderStatus::toArray();  // Perfect for 

More posts