## Основы перечислений

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

    <?php

    enum Suit
    {
        case Hearts;
        case Diamonds;
        case Clubs;
        case Spades;
    }

Это объявление создаёт новый перечислимый тип с именем `Suit`, у которого четыре и только четыре допустимых значения: `Suit::Hearts`, `Suit::Diamonds`, `Suit::Clubs` и `Suit::Spades`. Переменным разрешается присваивать только эти допустимые значения. В функциях разрешается указывать подсказку типа, которая проверит соответствие типа аргумента типу перечисления, чтобы в функцию передавали только значения, которые принадлежат заданному типу перечисления.

    <?php

    enum Suit
    {
        case Hearts;
        case Diamonds;
        case Clubs;
        case Spades;
    }

    function pick_a_card(Suit $suit)
    {
        var_dump($suit);
    }

    $val = Suit::Diamonds;

    // OK
    pick_a_card($val);

    // OK
    pick_a_card(Suit::Clubs);

    // TypeError: pick_a_card(): Argument #1 ($suit) must be of type Suit, string given
    pick_a_card('Spades');

Перечисления содержат ноль или больше определений `case`, без ограничения максимального количества. Перечисление без вариантов синтаксически корректно, хотя и бесполезно.

Для вариантов перечисления работают те же правила синтаксиса, что и для любой метки в PHP, смотрите раздел «Константы».

По умолчанию варианты не поддерживаются скалярным значением, поэтому `Suit::Hearts` не равно `"0"`. Вместо этого каждый вариант поддерживается одноэлементным объектом с таким именем. Это означает, что:

    <?php

    enum Suit
    {
        case Hearts;
        case Diamonds;
        case Clubs;
        case Spades;
    }

    $a = Suit::Spades;
    $b = Suit::Spades;

    if ($a === $b) {
        print "Масти совпадают по ===\n";
    }

    if ($a instanceof Suit) {
        print "Масти совпадают по instanceof\n";
    }

    if ($a !== 'Spades') {
        print "Масть не совпадает со строкой\n";
    }

Это также означает, что значения перечисления не будут `<` или `>` друг с друга, поскольку эти сравнения не имеют смысла для объектов. Сравнения каждый раз будут возвращать `false` при работе с вариантами перечисления.

Тип варианта без связанных данных называется «Чистый вариант» (англ. Pure Case). Перечисление, которое содержит только чистые варианты, называется чистым перечислением (англ. Pure Enum).

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

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

    <?php

    enum Suit
    {
        case Hearts;
        case Diamonds;
        case Clubs;
        case Spades;
    }

    print Suit::Spades->name;
    // Вывод: "Spades"

Содержится ли вариант в перечислении, возможно проверить по динамическому названию варианта, которое передают в функцию defined(), а считывают вариант по динамическому имени функцией constant(), но делать так не рекомендуется, поскольку в большей части сценариев работы с вариантами справляются типизированные перечисления.

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open