Как из enum получить список значений (labels)?

«Как из enum получить список значений (labels)?» — вопрос из категории PHP Core, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В PHP 8.1+ есть несколько чистых способов получить массив значений (labels) из перечисления (enum).

Способ 1: Для Backed Enums (скалярных) — используем value. Если enum реализует строковый или целочисленный тип, можно получить массив [case_name => value]:

enum Status: string {
    case PENDING = 'В обработке';
    case APPROVED = 'Подтверждено';
    case REJECTED = 'Отклонено';
}

// Получить массив всех значений
$labels = array_column(Status::cases(), 'value');
// Результат: ['В обработке', 'Подтверждено', 'Отклонено']

// Получить ассоциативный массив [имя_кейса => значение]
$mappedLabels = array_column(Status::cases(), 'value', 'name');
// Результат: ['PENDING' => 'В обработке', 'APPROVED' => 'Подтверждено', ...]

Способ 2: Добавить метод labels() в сам enum (рекомендуется). Это создает чистый, инкапсулированный API для перечисления:

enum Status: string {
    case PENDING = 'pending';
    case DONE = 'done';

    public function label(): string {
        return match($this) {
            self::PENDING => 'В ожидании',
            self::DONE => 'Завершено',
        };
    }

    public static function labels(): array {
        // Возвращает ассоциативный массив [значение_кейса => его_лейбл]
        return array_combine(
            array_column(self::cases(), 'value'),
            array_map(fn($case) => $case->label(), self::cases())
        );
    }
}

// Использование
$allLabels = Status::labels();
// Результат: ['pending' => 'В ожидании', 'done' => 'Завершено']

// Получить лейбл для конкретного экземпляра
$status = Status::PENDING;
echo $status->label(); // 'В ожидании'

Способ 3: Для Pure Enums (нескалярных) — только через метод.

enum Role {
    case ADMIN;
    case EDITOR;
    case VIEWER;

    public function label(): string {
        return match($this) {
            self::ADMIN => 'Администратор',
            self::EDITOR => 'Редактор',
            self::VIEWER => 'Наблюдатель',
        };
    }
}

$roleLabels = array_map(fn($case) => $case->label(), Role::cases());