Как использовать Enum в PHP 8

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

Перечисления (enums) — это тип данных, который можно использовать для хранения значения из пользовательского набора. Они идеально подходят для представления тех вариантов, которые вы можете отображать в раскрывающемся списке.

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

Что делают ENUM

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

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

Основные ENUM

Enum обычно хранят скалярные значения. Они аналогичны примитивным типам данных C, хотя перечисления PHP могут хранить не только целые числа, но и строковые значения. Однако по умолчанию перечисляемые значения PHP не имеют скалярного эквивалента. Они известны как базовые перечисления:

 enum Season
{
    case Spring;
    case Summer;
    case Autumn;
    case Winter;
}

Обратите внимание, как PHP повторно использует ключевое слово case, которое вы также встретите в операторах переключения. Значения, которые представляет это перечисление, являются просто именами случаев. Вы можете обратиться к определенному значению перечисления, используя следующий синтаксис:

 EnumTypeName::EnumField 

Например, для обозначения зимы используйте:

 Season::Winter 

Вы можете присвоить это значение переменной и сравнить его с другими значениями сезона:

 $favorite = Season::Summer;
 
if ($favorite == get_current_season()) {
    echo "It's my favorite season!";
}

Используя подсказку типа, вы можете ограничить параметры или возвращаемые типы определенным перечислением. Это помогает избежать целого набора ошибок и в целом делает ваш код более удобным в сопровождении:

 function get_current_season(): Season
{
    $day = date("z");
 
    if ($day < 59 || $day > 333) return Season::Winter;
    if ($day < 151) return Season::Spring;
    if ($day < 243) return Season::Summer;
    if ($day < 334) return Season::Autumn;
}

Если бы эта функция get_current_ Season попыталась вернуть что-то кроме сезона, PHP выдал бы фатальную ошибку TypeError.

Поддерживаемые ENUM

PHP использует термин «поддерживаемое перечисление» для обозначения перечисления со значениями. Это могут быть целые числа или строки:

 enum Month: int
{
    case Jan = 1;
    case Feb = 2;
    //...
}

Вам необходимо объявить тип поддерживаемого перечисления, и это должно быть либо int, либо строка.

Вы можете получить доступ к базовому значению, используя свойство значения, доступное только для чтения:

 echo Month::Jan->value; 

Когда вы используете поддерживаемые перечисления, вы также можете преобразовать в них эквивалентное скалярное значение, используя метод from:

 var_dump(Month::from(2)); 

Методы перечисления

Перечисления PHP также могут иметь методы, что делает их немного похожими на урезанный класс. Это отражает положение PHP как нечто среднее между процедурным языком и объектно-ориентированным языком.

Например, вы можете добавить этот простой метод к перечислению Month, чтобы получить количество дней из определенного значения:

 /* Note: no leap-year handling! */
function daysInMonth(): int {
    if ($this == Month::Feb) return 28;
    if (in_array($this, array(Month::Apr, Month::Jun, Month::Sep, Month::Nov))) return 30;
    return 31;
}

Обратите внимание, что вы можете использовать $this для ссылок в качестве значения перечисления точно так же, как вы используете $this для ссылок для текущего объекта. Вы также можете использовать стандартный оператор равенства == для сравнения показателей перечисления.

Перечисления также используют статические методы. Вероятность, они вам не нужны, но они могут быть полезны, если вам нужно написать что-то, работающее как конструктор, например:

 static function random(): Month {
    return Month::from(rand(1, count(Month::cases())));
}

Перечисления — общая особенность многих языков, включая предка PHP, C. Они являются одной из основных особенностей версии 8.1, позволяющей языку идти в ногу со многими своими конкурентами.

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