Перечисления
Статус заказа бывает «новый», «оплачен» или «отправлен» — и никакой другой. Если хранить его строкой, опечатка 'payed' пройдёт незамеченной. Перечисление задаёт закрытый список вариантов, и ничего кроме них в переменную не попадёт.
Объявление
Перечисление объявляют словом enum, варианты — словом case:
<?php
enum Status
{
case New;
case Paid;
case Shipped;
}
$status = Status::Paid;
echo $status->name; // PaidВариант — это объект. У каждого есть свойство name с его именем.
Перечисление как тип
Перечисление указывают в типе параметра — передать что-то другое не получится:
<?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)Варианты сравнивают через ===.
Значения
Чтобы сохранить вариант в базе или передать в JSON, ему задают значение — строку или число. После имени перечисления указывают тип значений:
<?php
enum Status: string
{
case New = 'new';
case Paid = 'paid';
}
echo Status::Paid->value; // paidСоздание из значения
from() находит вариант по значению и выбрасывает ошибку, если такого нет. tryFrom() в этом случае возвращает null:
<?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)Так строку из формы или из базы превращают в вариант перечисления.
Методы
Перечисление может содержать методы — обычно с match по вариантам:
<?php
enum Status: string
{
case New = 'new';
case Paid = 'paid';
public function label(): string
{
return match ($this) {
Status::New => 'Новый',
Status::Paid => 'Оплачен',
};
}
}
echo Status::New->label(); // НовыйЕсли добавить вариант и забыть про него в match, программа сообщит об ошибке при первом же обращении.
Все варианты
Метод cases() возвращает список всех вариантов — например, для выпадающего списка:
<?php
enum Size: string
{
case Small = 's';
case Medium = 'm';
case Large = 'l';
}
foreach (Size::cases() as $size) {
echo $size->value, ' ';
}Выведется s m l.
Частая ошибка
Вариант перечисления — не строка. Сравнение со строкой всегда даёт false, даже если значения совпадают:
<?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)Сравнивайте вариант с вариантом, а строку берите из свойства value.