How to enum in php

Enum в PHP 8.1 — для чего нужен enum, и как реализован в PHP

Через несколько дней заканчивается голосование по первой итерации реализации enum в PHP 8.1 . Уже видно, что голосов “за” гораздо больше, так что давайте кратко пройдемся и посмотрим, что же нам приготовили авторы языка.

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

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

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

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

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

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

Читайте также:  Css проверка заполнения поля

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

Pure enum

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

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

Из сигнатуры метода всё сразу видно, какие варианты есть. И метод 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. И у каждого кейса указать скалярное значение. Это может быть полезно для некоторых целей, например для сортировки или записи в базу данных.

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

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

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

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

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

interface Colorful < public function color(): string; >trait Rectangle < public function shape(): string < return "Rectangle"; >> enum Suit implements Colorful < use Rectangle; case Hearts; case Diamonds; case Clubs; case Spades; public function color(): string < return match($this) < Suit::Hearts, Suit::Diamonds =>'Red', Suit::Clubs, Suit::Spaces => 'Black', >; > >

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

Кстати, обратите внимание на работу с енамами в конструкции match. Похоже, match затевался именно для них.

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

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

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

И всё это не в Расте или Хаскеле, а в PHP!

Об этом мы расскажем в деталях в ближайших постах телеграм-канала Cross Join, не забудьте подписаться.

Источник

How to enum in php

Enumerations, or «Enums» allow a developer to define a custom type that is limited to one of a discrete number of possible values. That can be especially helpful when defining a domain model, as it enables «making invalid states unrepresentable.»

Enums appear in many languages with a variety of different features. In PHP, Enums are a special kind of object. The Enum itself is a class, and its possible cases are all single-instance objects of that class. That means Enum cases are valid objects and may be used anywhere an object may be used, including type checks.

The most popular example of enumerations is the built-in boolean type, which is an enumerated type with legal values true and false . Enums allows developers to define their own arbitrarily robust enumerations.

User Contributed Notes 1 note

It’s important to notice that the description here doesn’t describe Enum values as being constants. Some languages, like C, C++, and C#, think of an enum as a list of named integers, and working with enums in those languages is just working with integers. PHP does not do that.

In the same way that PHP’s booleans are their own type and not just constants with integer values 1 and 0, an Enum is its own type. It’s not a bunch of integers (or strings) that have been given names, and shouldn’t be thought of or used as such.

An Enum only needs to be backed by some primitive value like an integer or string if you need to communicate it outside the program (a message, UI, db storage, wire protocol, etc) where it has to be converted from/to its native PHP value (this is addressed again on the Backed Enumerations page). If you’re converting back and forth between Enums and their backing values inside your own program to get anything done then you might be missing the point of Enums.

You might want more structure to your Enum than just a pure set of distinct but otherwise nondescript values (you might at least want them to be ordered). But all that carry-on should be encapsulated within the Enum class itself via additional methods.

  • Enumerations
    • Enumerations overview
    • Basic enumerations
    • Backed enumerations
    • Enumeration methods
    • Enumeration static methods
    • Enumeration constants
    • Traits
    • Enum values in constant expressions
    • Differences from objects
    • Value listing
    • Serialization
    • Why enums aren’t extendable
    • Examples

    Источник

    How to enum in php

    Enumerations are a restricting layer on top of classes and class constants, intended to provide a way to define a closed set of possible values for a type.

    enum Suit
    case Hearts ;
    case Diamonds ;
    case Clubs ;
    case Spades ;
    >

    For a full discussion, see the Enumerations chapter.

    Casting

    If an enum is converted to an object , it is not modified. If an enum is converted to an array , an array with a single name key (for Pure enums) or an array with both name and value keys (for Backed enums) is created. All other cast types will result in an error.

    User Contributed Notes 1 note

    /**
    * This is a sample
    * How to use Enum to create a custom exception cases
    * PHP 8.1^
    */

    enum MyExceptionCase case InvalidMethod ;
    case InvalidProperty ;
    case Timeout ;
    >

    class MyException extends Exception function __construct (private MyExceptionCase $case ) match ( $case ) MyExceptionCase :: InvalidMethod => parent :: __construct ( «Bad Request — Invalid Method» , 400 ),
    MyExceptionCase :: InvalidProperty => parent :: __construct ( «Bad Request — Invalid Property» , 400 ),
    MyExceptionCase :: Timeout => parent :: __construct ( «Bad Request — Timeout» , 400 )
    >;
    >
    >

    // Testing my custom exception class
    try throw new MyException ( MyExceptionCase :: InvalidMethod );
    > catch ( MyException $myE ) echo $myE -> getMessage (); // Bad Request — Invalid Method
    >

    Источник

    How to enum in php

    Enums are similar to classes, and share the same namespaces as classes, interfaces, and traits. They are also autoloadable the same way. An Enum defines a new type, which has a fixed, limited number of possible legal values.

    This declaration creates a new enumerated type named Suit , which has four and only four legal values: Suit::Hearts , Suit::Diamonds , Suit::Clubs , and Suit::Spades . Variables may be assigned to one of those legal values. A function may be type checked against an enumerated type, in which case only values of that type may be passed.

    // 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’ );
    ?>

    An Enumeration may have zero or more case definitions, with no maximum. A zero-case enum is syntactically valid, if rather useless.

    For Enumeration cases, the same syntax rules apply as to any label in PHP, see Constants.

    By default, cases are not intrinsically backed by a scalar value. That is, Suit::Hearts is not equal to «0» . Instead, each case is backed by a singleton object of that name. That means that:

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

    It also means that enum values are never < or >each other, since those comparisons are not meaningful on objects. Those comparisons will always return false when working with enum values.

    This type of case, with no related data, is called a «Pure Case.» An Enum that contains only Pure Cases is called a Pure Enum.

    All Pure Cases are implemented as instances of their enum type. The enum type is represented internally as a class.

    All Cases have a read-only property, name , that is the case-sensitive name of the case itself.

    It is also possible to use the defined() and constant() functions to check for the existence of or read an enum case if the name is obtained dynamically. This is, however, discouraged as using Backed enums should work for most use cases.

    User Contributed Notes

    • Enumerations
      • Enumerations overview
      • Basic enumerations
      • Backed enumerations
      • Enumeration methods
      • Enumeration static methods
      • Enumeration constants
      • Traits
      • Enum values in constant expressions
      • Differences from objects
      • Value listing
      • Serialization
      • Why enums aren’t extendable
      • Examples

      Источник

Оцените статью