Home > Backend Development > PHP8 > PHP8.1 new features explained Enums enumeration

PHP8.1 new features explained Enums enumeration

藏色散人
Release: 2023-02-17 12:10:01
Original
4962 people have browsed it

This article is a translation, original address: https://stitcher.io/blog/php-enums

PHP 8.1: Enumerations

They're finally here - built-in support for enums will be added in PHP 8.1! Some may think they should have done this a long time ago, but you didn't hear my complaint; I'm glad they did! This article is dedicated to a deep dive into the newly added features.

As usual in my PHP feature posts, we start with a high-level overview of what enumerations look like:

enum Status
{
    case DRAFT;
    case PUBLISHED;
    case ARCHIVED;
}
Copy after login

The benefit of enumerations is that they represent a set of constant values, but The most important thing is that these values ​​can be typed like this:

class BlogPost
{
    public function __construct(
        public Status $status, 
    ) {}
}
Copy after login

In this example, creating an enum and passing it to aBlogPost looks like this:

$post = new BlogPost(Status::DRAFT);
Copy after login

That's it The basics, as you can see, they are not complicated at all. While there are a lot of side notes to make, let’s take a deeper look at enumerations!

#Enumeration methods

Enumerations can define methods, just like classes. This is a very powerful feature, especially when combined with the match operator:

enum Status
{
    case DRAFT;
    case PUBLISHED;
    case ARCHIVED;
    
    public function color(): string
    {
        return match($this) 
        {
            Status::DRAFT => 'grey',   
            Status::PUBLISHED => 'green',   
            Status::ARCHIVED => 'red',   
        };
    }
}
Copy after login

Methods can be used like this:

$status = Status::ARCHIVED;
$status->color(); // 'red'
Copy after login

Static methods are also allowed:

enum Status
{
    // …
    
    public static function make(): Status
    {
        // …
    }
}
Copy after login

You can also use self in an enumeration:

enum Status
{
    // …
    
    public function color(): string
    {
        return match($this) 
        {
            self::DRAFT => 'grey',   
            self::PUBLISHED => 'green',   
            self::ARCHIVED => 'red',   
        };
    }
}
Copy after login

#Enumeration interface

Enumerations can implement interfaces, just like ordinary classes:

interface HasColor
{
    public function color(): string;
}
enum Status implements HasColor
{
    case DRAFT;
    case PUBLISHED;
    case ARCHIVED;
    
    public function color(): string { /* … */ }
}
Copy after login

# Enumeration values ​​- aka "backed enums"

Enumeration values ​​are represented internally by objects, but you can assign values ​​to them as needed; this is useful for e.g. it works. Serialize them into the database.

enum Status: string
{
    case DRAFT = 'draft';
    case PUBLISHED = 'published';
    case ARCHIVED = 'archived';
}
Copy after login

Pay attention to the type declaration in the enumeration definition. It indicates that all enumeration values ​​belong to the given type. You can also make it an int. Note that onlyint and string are allowed as enumeration values.

enum Status: int
{
    case DRAFT = 1;
    case PUBLISHED = 2;
    case ARCHIVED = 3;
}
Copy after login

The technical term for type enums is called "backed enumerations" because they are "backed" by simpler values. If you decide to assign an enumeration value, all cases should have a value. You can't mix and match them. Enumerations without "backing" are called "pure enumerations".

#Supported enumerations with interfaces

If you use a supported enumeration with an interface, the enumeration type must come directly after the enumeration name, implements before the keyword.

enum Status: string implements HasColor
{
    case DRAFT = 'draft';
    case PUBLISHED = 'published';
    case ARCHIVED = 'archived';
    
    // …
}
Copy after login

#Serialization supported enums

If you are assigning values ​​to enum cases, you may need a way to serialize and deserialize them . Serializing them means you need a way to access the enum values. This is done via a read-only public property:

$value = Status::PUBLISHED->value; // 2
Copy after login

The enumeration can be restored from the value using: Enum::from

$status = Status::from(2); // Status::PUBLISHED
Copy after login

If an unknown value is passed tryFrom, there is also a return null. There is an exception if you use from.

$status = Status::from('unknown'); // ValueError
$status = Status::tryFrom('unknown'); // null
Copy after login

Please note that you can also use the built-in serialize and unserialize functions on enumerations. Additionally, you can use json_encode with a supported enumeration and the result will be an enumeration value. This behavior can be overridden by implementing JsonSerializable.

#Listing enumeration values

You can get a list of all available cases in an enumeration using the static method: Enum::cases()

Status::cases();
/* [
    Status::DRAFT, 
    Status::PUBLISHED, 
    Status::ARCHIVED
] */
Copy after login

Please note that this array contains the actual enumeration objects:

array_map(
    fn(Status $status) => $status->color(), 
    Status::cases()
);
Copy after login

#Enumerations are objects

I already mentioned that enumeration values ​​are represented as objects, actual Above they are singleton objects. This means you can compare to them like this:

$statusA = Status::PENDING;
$statusB = Status::PENDING;
$statusC = Status::ARCHIVED;
$statusA === $statusB; // true
$statusA === $statusC; // false
$statusC instanceof Status; // true
Copy after login

# Enums as Array Keys

Since enum values ​​are actually objects, there is currently no way to They are used as array keys. The following will result in an error:

$list = [
    Status::DRAFT => 'draft',
    // …
];
Copy after login

There is an RFC to change this behavior, but it has not been voted on yet.

This means you can only use enums as keys in SplObjectStorage and WeakMaps.

#Traits

Enumerations can use traits just like classes, but with more restrictions. Overriding built-in enumeration methods is not allowed, and they cannot contain class attributes - their use in enumerations is prohibited.

#Reflection and Properties

As expected, a few reflection classes have been added to handle enumerations: ReflectionEnum, ReflectionEnumUnitCase and ReflectionEnumBackedCase. There is also a new enum_exists function, which does exactly what its name suggests.

Just like ordinary classes and attributes, enumerations and their cases can be annotated using attributes. Note that the TARGET_CLASS filter will also include enumerations.

One last thing: the enumeration also has a read-only attribute, which the RFC mentions is an implementation detail and should only be used for debugging purposes. But it's still worth mentioning. $enum->name

The above is the detailed content of PHP8.1 new features explained Enums enumeration. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template