What is Enumerations(Enums) in PHP 8.1? Enums in PHP v8.1 Explained in detail with examples.
PHP 8.1 added many new features, and Enumerations (Enum) is our favourite new feature. Enumerations (or enums for short) allow us to define a new structure similar to a class however that can only hold a set of allowed values.
In this article, we’ll see the PHP v8.1 Enum feature, what is pure and backed cases in Enum, and the difference between regular Classes and Enums.
Basic Syntax
PHP 8.1 uses the enum
keyword to declare Enums. The syntax is similar to a trait
, class
, interface
syntax. Here is what a simple enum
looks like:
enum PostStatus {
case Draft;
case InReview;
case Published;
}
The case
keyword is used to describe the specific values the Enum accepts. The Enum cases are referenced in the same way as class constants:
$published = PostStatus::Published;
The advantage of enums is that they address a collection of constant values. Enums act in basically the same manner as classes and interfaces. So, you can type-hint that a function only accepts a value defined in an enum:
class PostService
{
public static function get(PostStatus $status)
{
}
}
In this example, you can pass the Enum to PostService::get()
method that looks like this:
$posts = PostService::get(PostStatus::Published);
Pure Enums
By default, Enumerated Cases have no scalar equivalent. They are simply singleton objects. So, if a case in Enum has no assigned value is called a pure case. And the Enum contains pure cases is called Pure Enum.
The PostStatus
above is pure Enum. It contains only case statements, with no extra data.
Backed Enums:
You can also attach a scalar value to enum cases, called backed cases. And the Enum contains backed cases called Backed Enum.
enum PostStatus: string
{
case Draft = "draft";
case InReview = "in_review";
case Published = "published";
}
Here the PostStatus
enum has been modified to create a backed enum.
Here are a few rules for backed Enums:
It must declare the scalar type at the Enum declaration. And only string or int is allowed.
It must assign a value for all cases.
The values assigned to each case must be of the same scalar type.
It must not contain duplicate cases or duplicate values.
Pure vs Backed Enums
Both pure enums and backed enums have a read-only property called name
, which returns the case-sensitive name of the case itself:
echo PostStatus::Draft->name; // Draft
Backed enums, however, have an additional read-only property called value
that returns the scalar value of the case:
echo PostStatus::Draft->value; // draft
Scalar Value to Enum
At the point when we want to get from the scalar value back to the Enum for that, we can utilize the from()
method. This method takes the string or integer value and converts it back to the Enum.
$draftStatus = PostStatus::from('draft');
If a value is passed that does not match the allowed values there will be a fatal error.
$draftStatus = PostStatus::from(100); // PHP fatal error
The above code will give PHP a fatal error because the value "100" is not present in the PostStatus
enum.
To make this safer PHP 8.1 gives us a tryFrom()
method that will return null instead of throwing an error.
$draftStatus = PostStatus::from(100); // null
Listing enum values
You can use the static Enum::cases()
method to get a list of all available cases inside an enum. This method returns an array containing the actual enum objects:
PostStatus::cases();
Class/object functions and instanceof
Enums act like classes when they are utilized with functions that help inspect classes and objects.
For instance, gettype()
, is_a()
, is_object()
, and get_class()
functions act as though an Enum is a standard PHP object.
gettype(PostStatus::Draft); // "object"
is_object(PostStatus::Draft); // true
is_a(PostStatus::Draft, PostStatus::InReview); // true
get_class(PostStatus::Published); // "PostStatus"
PostStatus::InReview instanceof PostStatus; // true
PostStatus::InReview instanceof UnitEnum; // true
Enums allow methods
Enums may contain methods. They also support standard method visibility modifiers as well as static methods.
For example, declaring a label(): string
method that returns a user-friendly label for an enum case.
enum PostStatus: int
{
case Draft = 0;
case InReview = 1;
case Published = 2;
public function label()
{
return match($this) {
self::Draft => 'Draft',
self::InReview => 'In Review',
self::Published => 'Published',
};
}
}
Enums must not contain properties
One of the main distinctions between an Enum and a class is that Enums cannot have any state/properties. Declaring properties is not allowed in Enums.
enum Foo {
private string $test;
private static string $test2;
}
/* Fatal error: Enums may not include properties ... */
Instantiating with new is not allowed
Although Enum cases themselves are objects, it is not allowed to instantiate them with the new
construct.
enum Foo {
case Bar;
}
new Foo();
/* Fatal error: Uncaught Error: Cannot instantiate ... */
Comparing Enum Values
As we already learned, Enums cases are as objects. In fact, those are singleton objects. That implies that you can do comparisons with them like so:
new stdClass() === new stdClass(); // false
PostStatus::Draft === PostStatus::Draft; // true
Disallowed magic methods
Enums disallow implementing several magic methods:
__get()
__set()
__construct()
__destruct()
__clone()
__sleep()
__wakeup()
__set_state()
Magic constants
Enums completely support all magic constants that PHP upholds for classes.
::class
__CLASS__
__FUNCTION__
__METHOD__
Classes vs Enums
Classes | Enums | |
Syntax |
|
|
Properties | ✔ | ✘ |
Static Properties | ✔ | ✘ |
Methods | ✔ | ✔ |
Static Methods | ✔ | ✔ |
Instantiating: | ✔ | ✘ |
Implement interfaces | ✔ | ✔ |
Inheritance: | ✔ | ✘ |
Magic Constants | ✔ | ✔ |
Traits | ✔ | ✔ (without properties) |
Please login or create new account to add your comment.