Перечисления в php

Перечисления, или Enums, разрешают разработчику определять настраиваемый тип, который ограничивается одним значением из дискретного числа возможных

    Общие сведения

    Основная идея перечислений — предоставить способ определения закрытого набора возможных значений для типа, что повышает читаемость кода и снижает вероятность ошибок.
    В PHP перечисления относятся к виду объектов. Сами перечисления — классы, а каждый возможный случай перечисления — объект одного экземпляра этого класса
    Перечисления похожи на классы и работают с теми же пространствами имён, что и классы, интерфейсы и трейты.
    Перечисления как и классы разрешается загружать автоматически.

    #перечислимый тип с именем Suit, у которого четыре и только четыре допустимых значения: enum Suit { case Hearts; case Diamonds; case Clubs; case Spades; }

    Каждый вариант содержит доступное только для чтения свойство name — чувствительное к регистру название самого варианта.

    enum Suit { case Hearts; case Diamonds; case Clubs; case Spades; } print Suit::Spades->name; // Вывод: "Spades"
    Типизированные перечисления

    Перечисление с типизированными вариантами называется «типизированным перечислением»
    Перечисления допускают поддержку единственным типом — int или string, поэтому типы нельзя объединять: int|string

    enum Suit: string { case Hearts = 'H'; case Diamonds = 'D'; case Clubs = 'C'; case Spades = 'S'; }

    Типизированное перечисление допускает только типизированные варианты, а чистое перечисление — только чистые.


    У типизированных вариантов есть дополнительное доступное только для чтения свойство value — это значение, заданное в определении варианта.

    enum Suit: string { case Hearts = 'H'; case Diamonds = 'D'; case Clubs = 'C'; case Spades = 'S'; } print Suit::Clubs->value; // Конструкция выведет "C"

    Типизированные перечисления реализуют внутренний интерфейс BackedEnum, который даёт два дополнительных метода:
    from(int|string): self возьмёт скаляр и вернёт вариант перечисления, которому он принадлежит. Если вариант, который соответствует варианту перечисления, не найден, метод выбросит исключение ValueError
    tryFrom(int|string): ?self возьмёт скаляр и вернёт вариант перечисления, которому он принадлежит. Если вариант, который соответствует варианту перечисления, не найден, метод вернёт null.

    #$suit = Suit::tryFrom('A') ?? Suit::Spades; // Недопустимые данные возвращают значение null, поэтому вместо этого будет использовано Suit::Spades
    Методы перечислений

    Перечисления (как чистые, так и типизированные) могут содержать методы и могут реализовывать интерфейсы. Если перечисление реализует интерфейс, то любая проверка типа этого интерфейса также примет и все варианты этого перечисления


    В этом примере каждый из четырёх экземпляров Suit имеет два метода: color() и shape()
    Переменная $this определена внутри метода и ссылается на экземпляр варианта.
    В перечислениях разрешено объявлять общедоступные, закрытые и защищённые методы, хотя на практике закрытые и защищённые методы эквивалентны, поскольку наследование не разрешено

    interface Colorful { public function color(): string; } enum Suit implements Colorful { case Hearts; case Diamonds; case Clubs; case Spades; // Выполняет контракт интерфейса. public function color(): string { return match ($this) { Suit::Hearts, Suit::Diamonds => 'Красный', Suit::Clubs, Suit::Spades => 'Чёрный' }; } // Не часть интерфейса; хорошо. public function shape(): string { return "Rectangle"; } } function paint(Colorful $c) { print $c->color() . "\n"; } paint(Suit::Clubs); // Работает print Suit::Diamonds->shape(); // выведет "Rectangle"
    Статические методы перечислений

    В перечислениях разрешено объявлять статические методы. Статические методы в самом перечислении в первую очередь выступают в роли альтернативных конструкторов.

    enum Size { case Small; case Medium; case Large; public static function fromLength(int $cm): self { return match(true) { $cm < 50 => self::Small, $cm < 100 => self::Medium, default => self::Large, }; } }

    В PHP self — это тип, который используется для указания того, что значение должно быть экземпляром того же класса, в котором используется объявление типа. Это относительный тип класса, который применяется внутри классов.


    Получить все скалярные эквивалентные значения Backed Enum в виде массива

    enum Suit: string { case Hearts = 'H'; case Diamonds = 'D'; case Clubs = 'C'; case Spades = 'S'; public static function values(): array { return array_column(self::cases(), 'value'); } }
    Константы перечислений

    В перечисления разрешено включать константы с общедоступной, закрытой или защищённой областью видимости, хотя на практике закрытые и защищённые константы эквивалентны, поскольку наследование не разрешено.
    Константе перечисления разрешено ссылаться на вариант перечисления:

    enum Size { case Small; case Medium; case Large; public const Huge = self::Large; } var_dump(Size::Huge);
    Трейты

    Перечисления поддерживают включение трейтов, которые ведут себя так же, как в классе.
    Предостережение состоит в том, что во включаемых (use) в перечисление трейтах нельзя объявлять свойства. Во включаемом в перечисление трейте разрешается объявлять только методы, статические методы и константы.

    enum Suit implements Colorful { use Rectangle; case Hearts; case Diamonds; case Clubs; case Spades; public function color(): string { return match ($this) { Suit::Hearts, Suit::Diamonds => 'Красный', Suit::Clubs, Suit::Spades => 'Чёрный', }; } }
    Значения перечисления в постоянных выражениях

    Поскольку в самом перечислении варианты объявлены константами, их разрешено использовать как статические значения в большей части константных выражений: значения по умолчанию для свойств, значения по умолчанию для статических переменных, значения по умолчанию для параметров, глобальные значения и значения констант класса. Их нельзя указывать как значения в других вариантах перечисления, но стандартные константы могут ссылаться на вариант перечисления.

    enum Direction implements ArrayAccess { case Up; case Down; } class Foo { // Это разрешено. const DOWN = Direction::Down; } $x = Direction::Up['short'];


    Источник: https://www.php.net/manual/ru/language.enumerations.expressions.php

    Отличия от объектов

    Хотя перечисления построены на классах и объектах, они не поддерживают полную объектно-связанную функциональность.

    Конструкторы и деструкторы запрещены.
    Наследование не поддерживается. Перечислениям нельзя наследовать или наследоваться.
    Статические свойства или свойства объекта не допускаются.
    Клонирование варианта перечисления не поддерживается, так как варианты должны быть одноэлементными экземплярами.
    Магические методы, кроме перечисленных ниже, запрещены.
    Перечисления должны быть объявлены до начала работы с ними.
    Перечислениям доступны следующие функциональные возможности объекта с аналогичным поведением:
    
    Методы public, private и protected.
    Статические методы public, private и protected.
    Константы public, private и protected.
    Перечислениям разрешено реализовывать любое количество интерфейсов.
    К перечислениям и вариантам разрешено добавлять атрибуты. Целевой фильтр TARGET_CLASS включает сами перечисления. Целевой фильтр TARGET_CLASS_CONST включает варианты перечислений.
    Магические методы __call, __callStatic, и __invoke.
    Константы __CLASS__ и __FUNCTION__ ведут себя как обычно.
    

    Источник: https://www.php.net/manual/ru/language.enumerations.object-differences.php

    Список значений

    И чистые, и типизированные перечисления реализуют внутренний интерфейс с именем UnitEnum. Интерфейс UnitEnum включает статический метод cases(). Метод cases() возвращает упакованный массив вариантов, которые определили в перечислении. Варианты возвращаются в порядке объявления.

    enum Suit { case Hearts; case Diamonds; case Clubs; case Spades; } var_dump(Suit::cases()); enum SuitBacked: string { case Hearts = 'H'; case Diamonds = 'D'; case Clubs = 'C'; case Spades = 'S'; } var_dump(SuitBacked::cases());
    Сериализация

    Перечисления сериализуются иначе, чем объекты.
    Подробнее: https://www.php.net/manual/ru/language.enumerations.serialization.php

    Примеры использования перечислений

    https://www.php.net/manual/ru/language.enumerations.examples.php


    Источники
    Последнее изменение: 16.05.2026 14:20


    Здесь пока нет комментариев
    Добавлять комментарии могут только авторизованные пользователи

    Авторизоваться
    Я буду рекламой
    Я тоже буду рекламой
    И я
    ВВЕРХ