As of PHP 8.1, the Enum data type can be used to define exact enumeration values for a list. This is useful for cases where we know that the value of a variable can only take on a specific few values.
For example, this is how I store notification types:
enum OrderNotificationType: string{case Email = 'email';case Sms = 'text';}
In PHP, the Enum data type is a classic object that behaves like a special type of constant, but also has an instance that can be passed on. However, unlike a regular object, it is subject to a number of restrictions.
Although enums are built on top of classes and objects, they do not support all the functionality associated with objects. In particular, enum objects are prohibited from having internal state (they must always be a static class).
A specific list of differences:
The following object features are available and behave just like any other object:
TARGET_CLASS
includes the Enums themselves. The target filter TARGET_CLASS_CONST
includes Enum cases.__call
, __callStatic
and __invoke
.__CLASS__
and __FUNCTION__
behave like normal constants::class
on the Enum type is evaluated as the full name of the data type, including any namespace, exactly as for an object. The magic constant ::class
on an instance of type Case
is also evaluated as type Enum, since it is an instance of a different type.Imagine we have an enum representing the types of suits. In this case, we just need to define the Suit
type and store the individual valid values.
We then get an instance of the particular option classically via a quadratic, as when working with a static constant.
Example of defining an Enum, invoking it by a specific type and passing it to a function:
enum Suit{case Hearts;case Diamonds;case Clubs;case Spades;}function doStuff(Suit $s){// ...}doStuff(Suit::Spades);
The fundamental advantage of enums over objects and constants is that it is easy to compare their values.
A basic comparison that we work with a specific value can be done as follows:
$a = Suit::Spades;$b = Suit::Spades;$a === $b; // true
Very often we also need to decide that a particular value belongs in a valid Enum value enumeration. This can be easily verified as follows:
$a = Suit::Spades;$a instanceof Suit; // true
We can read a specific type value either as a name of a calling constant or directly as a real defined value (if it exists):
enum Colors{case Red;case Blue;case Green;public function getColor(): string{return $this->name;}}function paintColor(Colors $colors): void{echo "Paint:" . $colors->getColor();}
The value of the calling constant is read via the name
property. It is also important that a custom function can be implemented directly in the Enum data type, which can be called over each Enum.
If a particular Enum also implements real values (which are hidden under each constant), their value can be read as well:
enum OrderNotificationType: string{case Email = 'email';case Sms = 'text';}$type = OrderNotificationType::Email;echo $type->value;
Often we need to list (for example, to the user in an error message) all possible values that Enum can take. When using constants this was not possible, Enum allows this easily:
Suit::cases();
Returns [Suit::Hearts, Suit::Diamonds, Suit::Clubs, Suit::Spades]
.
We can easily verify that a particular unknown variable contains Enum by a condition:
if ($haystack instanceof \BackedEnum) {
Each Enum object is automatically a child of the generic \BackedEnum
interface.
For more information, see the discussion on the PhpStan GitHub: https://github.com/phpstan/phpstan/issues/7304
Jan Barášek Více o autorovi
Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.
Rád vám pomůžu:
Články píše Jan Barášek © 2009-2024 | Kontakt | Mapa webu
Status | Aktualizováno: ... | en