Так. Enum у PHP - повноцінний тип: він може мати методи (звичайні й статичні), константи, реалізовувати інтерфейси й використовувати трейти (без властивостей).
interface HasLabel
{
public function label(): string;
}
enum OrderStatus: string implements HasLabel
{
case New = 'new';
case Paid = 'paid';
case Shipped = 'shipped';
public const DEFAULT = self::New;
public function label(): string
{
return match ($this) {
self::New => 'Нове',
self::Paid => 'Оплачене',
self::Shipped => 'Відправлене',
};
}
public function isFinal(): bool
{
return $this === self::Shipped;
}
public static function forSelect(): array
{
return array_combine(
array_column(self::cases(), 'value'),
array_map(fn (self $s) => $s->label(), self::cases()),
);
}
}
$order->status->label(); // 'Оплачене'
OrderStatus::DEFAULT; // OrderStatus::New
Навіщо це: вся поведінка, пов'язана з переліком, живе в одному місці. Замість if ($status === 'paid' || $status === 'shipped'), розкиданих по коду, - $status->isFinal(). Додали новий варіант - match без default змусить оновити кожен метод.
Інтерфейси дозволяють використовувати різні enum однаково: Filament і багато бібліотек розпізнають інтерфейси на кшталт HasLabel, HasColor, HasIcon і самі показують мітку, колір і іконку.
Обмеження:
- Немає властивостей (стану) - лише константи.
- Не можна успадкувати один enum від іншого.
- Трейти - лише без властивостей.
- Магічні методи заборонені, крім
__call,__callStaticі__invoke.