What is Enumerations(Enums) in PHP 8.1? Enums in PHP v8.1 Explained in detail with examples.

Harish Kumar · · 6273 Views

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:

  1.  It must declare the scalar type at the Enum declaration. And only string or int is allowed.

  2. It must assign a value for all cases.

  3. The values assigned to each case must be of the same scalar type.

  4. 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:

  1. __get()

  2. __set()

  3. __construct()

  4. __destruct()

  5. __clone()

  6. __sleep()

  7. __wakeup()

  8. __set_state()

Magic constants

Enums completely support all magic constants that PHP upholds for classes.

  1. ::class

  2. __CLASS__

  3. __FUNCTION__

  4. __METHOD__

Classes vs Enums

Classes

Enums

Syntax

class Foo {}

enum Foo {}

Properties



Static Properties

Methods

Static Methods

Instantiating: new Foo()

Implement interfaces

Inheritance: Foo extends Bar

Magic Constants

Traits

✔ (without properties)

0

Please login or create new account to add your comment.

0 comments
You may also like:

PHP 8.4 Property Hooks: The Ultimate Guide for Developers

PHP 8.4, coming in November 2024, introduces a new feature called property hooks. This feature makes it easier to work with class properties by allowing you to define custom behavior (...)
Harish Kumar

PHP OPCache: The Secret Weapon for Laravel Performance Boost

OPCache, a built-in PHP opcode cache, is a powerful tool for significantly improving Laravel application speed. This guide will demonstrate how to effectively utilize OPCache to (...)
Harish Kumar

PHP Security Guide: Strategies for Safe and Secure Code

PHP is one of the most widely used server-side scripting languages for web development, powering millions of websites and applications. Its popularity is largely due to its ease (...)
Harish Kumar

How to Use DTOs for Cleaner Code in Laravel, Best Practices and Implementation Guide

When developing APIs in Laravel, ensuring your responses are clear, concise, and consistent is crucial for creating a maintainable and scalable application. One effective way to (...)
Harish Kumar

Data Transfer Objects (DTOs) in PHP: Streamlining Data Flow and Enhancing Code Clarity

Data Transfer Objects (DTOs) are simple objects used to transfer data between software application subsystems. They help in encapsulating data and reducing the number of method (...)
Harish Kumar

PHP Generators: Efficient Data Handling and Iteration Techniques

PHP Generators offer a powerful and memory-efficient way to handle large datasets and complex iteration scenarios in your applications. They provide a more elegant solution compared (...)
Harish Kumar