Enums: Backed, Methods and Interfaces
Enums model a fixed set of named values as real objects. Back them with a scalar, give them methods, even have them implement interfaces.
Since PHP 8.1, an enum replaces the old habit of loose class constants with a proper type. A variable typed as Suit can only ever hold one of the declared cases — the compiler guarantees it.
Pure vs backed
A pure enum has only names. A backed enum ties each case to a scalar (string or int), which is what you store in a database and rebuild with from() / tryFrom().
<?php
enum Status: string {
case Draft = 'draft';
case Published = 'published';
}
$s = Status::from('draft');
echo $s->name; // Draft
echo $s->value; // draft
var_dump(Status::tryFrom('nope')); // null, no exceptionEnums can hold methods and constants, and can implement interfaces — so they carry behaviour, not just identity.
Example
When to use it
- Model an order's lifecycle (Pending, Processing, Shipped, Delivered, Cancelled) as a backed enum for type-safe status storage.
- Add a label() method to a Status enum so views can display human-friendly text without a separate lookup array.
- Implement the Stringable interface on a backed enum so it can be embedded directly in SQL queries.
More examples
Backed enum with string values
Backed enums store a scalar value with each case; from() reconstructs the enum from a stored database string.
<?php
enum Status: string {
case Pending = 'pending';
case Processing = 'processing';
case Shipped = 'shipped';
case Cancelled = 'cancelled';
}
$order = Status::Pending;
echo $order->value; // pending
$from_db = Status::from('shipped');
echo $from_db->name; // ShippedEnum with methods
Enum methods let you attach behaviour to each case, replacing switch statements scattered around the codebase.
<?php
enum Suit: string {
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
public function color(): string {
return match($this) {
self::Hearts, self::Diamonds => 'red',
self::Clubs, self::Spades => 'black',
};
}
public function label(): string {
return $this->name . ' (' . $this->value . ')';
}
}
echo Suit::Hearts->color(); // red
echo Suit::Spades->label(); // Spades (S)Enum implementing an interface
Enums can implement interfaces, allowing them to be used wherever the interface is type-hinted.
<?php
interface HasLabel {
public function label(): string;
}
enum Priority: int implements HasLabel {
case Low = 1;
case Medium = 2;
case High = 3;
public function label(): string {
return match($this) {
self::Low => 'Low Priority',
self::Medium => 'Medium Priority',
self::High => 'High Priority',
};
}
}
$tasks = Priority::cases();
foreach ($tasks as $t) {
echo "{$t->value}: {$t->label()}\n";
}
Discussion