TGViewer
Cross Join - канал о разработке Cross Join - канал о разработке @crossjoin · 3.83K subscribers
Post #22 573
Через несколько дней заканчивается голосование по первой итерации реализации enum в PHP 8.1 (https://wiki.php.net/rfc/enumerations#voting ). Уже видно, что голосов “за” гораздо больше, так что давайте кратко пройдемся и посмотрим, что же нам приготовили авторы языка.

Зачем нужны enum?

Зачем вообще нужны enum? По сути они служат цели улучшенного описания типов. Давайте рассмотрим пример без енумов и с ними. Допустим, у нас продаются машины трех цветов: красные, черные и белые. Как описать цвет, какой тип выбрать?


class Car {
private string $color;

function setColor(string $color): void {
$this->color = $color;
}
}


Если мы опишем цвет машины как простой string, то во-первых при вызове $myCar->setColor(..) непонятно, что за строку туда писать. “red” или “RED” или "ff0000", а во вторых, легко ошибиться, просунув туда случайно что-то не то (пустую строку, к примеру). То же самое будет, если использовать не строки, а числа, например.

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


class Color {
public const RED = "red";
public const BLACK = "black";
public const WHITE = "white";
}


и задавая цвет, пишут $myCar->setColor(Color::RED);

Уже лучше. Но если мы впервые видим метод $myCar->setColor(...), мы можем и не знать, что где-то есть константы для цветов. И мы всё еще можем сунуть туда любую строку без какого-либо сообщения об ошибке.

Поэтому здесь нужен не класс, а отдельный тип. Этот тип называется enum

Pure enum

В самом простом случае (pure enum), enum описывается так:

enum Color {
case Red;
case Black;
case White;
}


Описав такой тип, мы можем использовать его везде:


class Car {
private Color $color;

function setColor(Color $color): void {
$this->color = $color;
}
}


Из сигнатуры метода всё сразу видно, какие варианты есть. И метод setColor можно использовать только так: $myCar->setColor(Color::White), никаких строк и доморощенных списков констант. Ничего лишнего не сунешь. Читабельность и поддерживаемость кода стала выше.

Каждый из case-ов (Color::Red, Color::Black, Color::White) является объектом типа Color (можно проверить через instanseof ). Т.е. под капотом это не числа 0,1,2 как в некоторых языках, а именно объекты. Их нельзя сравнивать оператором >, например. У каждого такого объекта есть встроенное свойство $name:

print Color::Red->name; // вернет строку “Red”

Enum со скалярами

Но если бы это было всё, то было бы слишком просто. После названия enum можно указать скалярный тип, например string. И у каждого кейса указать скалярное значение. Это может быть полезно для некоторых целей, например для сортировки или записи в базу данных.


enum Color: string {
case Red = "R";
case Black = "B";
case White = "W";
}


Скалярное значение можно получить потом так:

Color::Red->value //вернет строку “R”


И наоборот, т.е. получить case через значение, тоже можно:


Color::from("R") // вернет объект Color::Red

Помимо полей "case" в enum может быть еще много всего. По сути это разновидность класса. Там могут быть методы, он может реализовывать интерфейсы или использовать трейты:

https://gist.github.com/anton-okolelov/f5e8787b6dfe9b28cbeef7bf5fa9e611

При этом $this будет тот конкретный объект case, для которого мы вызываем метод.

Лично я горячо одобряю введение enum в PHP, это очень удобно и читабельно, и в большинстве языков, где есть какие-никакие типы, enum уже давно есть (кроме, разве что Go).

Дальше - больше. Tagged Unions (тип-сумма)

Есть RFC, которые развивают идею enums дальше, чтобы можно было хранить в одном enum значения разных типов. Как в языке Rust, например. Тогда можно будет сделать, допустим, enum Result с двумя case-ами Result::Ok и Result::Err, причем эти объекты будут хранить данные: Ok будет хранить результат, а Err - ошибку, у каждого из этих значений будет свой тип. И всё это не в Расте, а в PHP!

Об этом мы расскажем в деталях в ближайших постах телеграм-канала Cross Join, не забудьте подписаться!
  • 👀 1
More from @crossjoin
  1. Oct 2, 2026Теперь у нас у всех есть простой способ поддерживать знание иностранного языка. Просто раз…
  2. Oct 2, 2026Вышел NATS Server 2.15.0 Самое важное: • Надёжнее работа JetStream-кластера. Масштабирован…
  3. Sep 29, 2026😱 Отправили свое резюме на 129 вакансий на хх, а в ответ тишина .. Думаете, что дело в ры…
  4. Sep 28, 2026Слышал недавно в каком-то подкасте мысль, что Haskell плохо подходит для вайбкодинга прост…
  5. Sep 26, 2026Антон Жиянов написал мини-книгу по Go-concurrency. Это что-то вроде плотного конспекта с и…
  6. Sep 22, 2026photo post
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →