Enumerations
An order status is "new", "paid" or "shipped" — and nothing else. If it is stored as a string, the typo 'payed' slips through unnoticed. An enumeration defines a closed list of options, and nothing but them can get into the variable.
Declaring
An enumeration is declared with the word enum, its options with the word case:
<?php
enum Status
{
case New;
case Paid;
case Shipped;
}
$status = Status::Paid;
echo $status->name; // PaidA case is an object. Each has a name property holding its name.
An enumeration as a type
An enumeration is used as a parameter type — nothing else can be passed:
<?php
enum Status
{
case New;
case Paid;
}
function canShip(Status $status): bool
{
return $status === Status::Paid;
}
var_dump(canShip(Status::Paid)); // bool(true)
var_dump(canShip(Status::New)); // bool(false)Cases are compared with ===.
Values
To store a case in a database or send it in JSON, give it a value — a string or a number. The type of the values goes after the enumeration's name:
<?php
enum Status: string
{
case New = 'new';
case Paid = 'paid';
}
echo Status::Paid->value; // paidCreating from a value
from() finds a case by its value and throws an error if there is none. tryFrom() returns null in that situation:
<?php
enum Status: string
{
case New = 'new';
case Paid = 'paid';
}
echo Status::from('paid')->name, "\n"; // Paid
var_dump(Status::tryFrom('unknown') === null); // bool(true)This is how a string from a form or a database becomes an enumeration case.
Methods
An enumeration can have methods — usually with a match over the cases:
<?php
enum Status: string
{
case New = 'new';
case Paid = 'paid';
public function label(): string
{
return match ($this) {
Status::New => 'New order',
Status::Paid => 'Paid order',
};
}
}
echo Status::New->label(); // New orderIf a case is added and forgotten in the match, the program reports an error on the very first access.
Every case
The cases() method returns the list of all cases — for a dropdown, for example:
<?php
enum Size: string
{
case Small = 's';
case Medium = 'm';
case Large = 'l';
}
foreach (Size::cases() as $size) {
echo $size->value, ' ';
}This prints s m l.
Common mistake
An enumeration case is not a string. Comparing it with a string always gives false, even if the values match:
<?php
enum Status: string
{
case Paid = 'paid';
}
$status = Status::Paid;
var_dump($status === 'paid'); // bool(false)
var_dump($status->value === 'paid'); // bool(true)
var_dump($status === Status::Paid); // bool(true)Compare a case with a case, and take the string from the value property.