## Значения перечисления в постоянных выражениях

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

Однако неявные вызовы магических методов, как это происходит при реализации интерфейса ArrayAccess в перечислениях, — не допускаются в статических или константных определениях, поскольку невозможно абсолютно гарантировать, что результирующее значение будет детерминированным или при вызове метода не возникнет побочных эффектов. Вызовы функций, вызовы методов и доступ к свойствам по-прежнему недопустимы в постоянных выражениях.

    <?php

    // Это на 100 % корректное определение перечисления.
    enum Direction implements ArrayAccess
    {
        case Up;
        case Down;

        public function offsetExists($offset): bool
        {
            return false;
        }

        public function offsetGet($offset): mixed
        {
            return null;
        }

        public function offsetSet($offset, $value): void
        {
            throw new Exception();
        }

        public function offsetUnset($offset): void
        {
            throw new Exception();
        }
    }

    class Foo
    {
        // Это разрешено.
        const DOWN = Direction::Down;

        // Это запрещено, так как не может быть детерминированным.
        const UP = Direction::Up['short'];
        // Fatal error: Cannot use [] on enums in constant expression
    }

    // Это совершенно законно, потому что это не постоянное выражение.
    $x = Direction::Up['short'];
    var_dump("\$x – это " . var_export($x, true));

    $foo = new Foo();

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