Перечисления похожи на классы и работают с теми же пространствами имён, что и классы, интерфейсы и трейты. Перечисления как и классы разрешается загружать автоматически. Перечисления определяют новый тип с фиксированным ограниченным количеством возможных допустимых значений.
<?php
enum Suit
{
case Hearts;
case Diamonds;
case Clubs;
case Spades;
}
?>
Это объявление создаёт новый перечислимый тип с именем Suit
, у которого четыре и только четыре
допустимых значения: Suit::Hearts
, Suit::Diamonds
,
Suit::Clubs
и Suit::Spades
.
Переменным разрешается присваивать только эти допустимые значения.
В функциях разрешается указывать подсказу типа, которая проверит соответствие типа аргумента
типу перечисления, чтобы в функцию передавали только значения, которые принадлежат заданному типу перечисления.
<?php
function pick_a_card(Suit $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
$a = Suit::Spades;
$b = Suit::Spades;
$a === $b; // true
$a instanceof Suit; // true
?>
Это также означает, что значения перечисления не будут <
или >
друг с друга, поскольку эти сравнения не имеют смысла для объектов.
Сравнения каждый раз будут возвращать false
при работе с вариантами перечисления.
Тип варианта без связанных данных называется «Чистый вариант» (англ. Pure Case). Перечисление, которое содержит только чистые варианты, называется чистым перечислением (англл. Pure Enum).
Каждый чистый вариант реализуется как экземпляр своего типа перечисления. Тип перечисления внутренне представлен как класс.
Каждый вариант содержит доступное только для чтения свойство name
—
чувствительное к регистру название самого варианта.
<?php
print Suit::Spades->name;
// prints "Spades"
?>
Функции defined() и constant() умеют проверять, определи ли перечисление, и считывать регистр перечисления, если имя получили динамически. Однако поступать так не рекомендуют, поскольку часто лучше работать с типизированными перечислениями.