Примеры

Пример #1 Базовые ограниченные значения

<?php

enum SortOrder
{
    case Asc;
    case Desc;
}

function query($fields, $filter, SortOrder $order = SortOrder::Asc)
{
     /* ... */
}

Функция query() теперь безопасно выполняется, поскольку знает, что в параметр $order гарантированно примет либо вариант SortOrder::Asc, либо вариант SortOrder::Desc. Другое значение выбросило бы ошибку TypeError, поэтому функция обойдётся без проверки ошибок или тестирования.

Пример #2 Расширенные эксклюзивные значения

<?php

enum UserStatus: string
{
    case Pending = 'P';
    case Active = 'A';
    case Suspended = 'S';
    case CanceledByUser = 'C';

    public function label(): string
    {
        return match ($this) {
            self::Pending => 'В ожидании',
            self::Active => 'Активный',
            self::Suspended => 'Приостановленный',
            self::CanceledByUser => 'Отменён пользователем',
        };
    }
}

$status = UserStatus::Suspended;
var_dump($status->label());

В этом примере статус пользователя ограничивается единственным значением и только из следующих вариантов: UserStatus::Pending, UserStatus::Active, UserStatus::Suspended или UserStatus::CanceledByUser. Определение в сигнатуре функции параметра с типом UserStatus разрешит функции принимать только эти четыре значения, точка.

Каждому из четырёх значений доступен метод label(), который возвращает строку, удобную для чтения человеком. Эта строка не зависит от строки со скалярным эквивалентом «машинного имени», который, например, хранят в поле базы данных или выводят как значение элемента выпадающего списка в HTML-форме.

<?php

enum UserStatus: string
{
    case Pending = 'P';
    case Active = 'A';
    case Suspended = 'S';
    case CanceledByUser = 'C';

    public function label(): string
    {
        return match($this) {
            self::Pending => 'В ожидании',
            self::Active => 'Активный',
            self::Suspended => 'Приостановленный',
            self::CanceledByUser => 'Отменён пользователем',
        };
    }
}

foreach (UserStatus::cases() as $case) {
    printf(
        "<option value=\"%s\">%s</option>\n",
        htmlentities($case->value),
        htmlentities($case->label())
    );
}

Добавить

Примечания пользователей 1 note

up
20
php-net at mentordosnerds dot com
2 years ago
Additional use-case examples:
<?php

trait EnumNamesTrait
{
    abstract public static function cases(): array;
    
    public static function names(): array
    {
        return array_map(fn($enum) => $enum->name, static::cases());
    }
}

trait EnumValuesTrait
{
    abstract public static function cases(): array;
    
    public static function values(): array
    {
        return array_map(fn($enum) => $enum->value, static::cases());
    }
}

trait EnumArraySerializableTrait
{
    use EnumNamesTrait;
    use EnumValuesTrait;
    
    public static function array(): array
    {
        return array_combine(static::names(), static::values());
    }
}

trait EnumJsonSerializableTrait
{
    use EnumArraySerializableTrait;
     
    public static function jsonSerialize(): string
    {
        return json_encode(static::array());
    }
}

enum Suit: string
{
    case Clubs = '♣';
    case Diamonds = '♦';
    case Hearts = '♥';
    case Spades = '♠';
 
    use EnumJsonSerializableTrait;
    
    public const DEFAULT = self::Hearts;
    
    public static function default(): static
    {
        return self::DEFAULT;
    }
}

var_dump(
    Suit::cases(),
    Suit::values(), 
    Suit::names(),
    Suit::array(),
    Suit::jsonSerialize(),
    Suit::default(),
);
To Top