Programster's Blog

Tutorials focusing on Linux, programming, and open-source

PHP Enums

Enums is the biggest of the new features that came with PHP 8.1. This post will outline everything to do with enums in PHP, and will be updated as they change in future releases of the PHP language.

Table of Contents

  1. Creation and Usage
  2. Methods
  3. Interfaces
  4. Typed Enums
  5. Retrieve Value
  6. Create from Value
  7. Serialize
  8. Cases method - Get Array of Cases
  9. Comparing Enums
  10. Array Keys

Creation And Usage

Declare an enum like so:

enum Status
{
    case DRAFT;
    case PUBLISHED;
    case ARCHIVED;
}

Define a class that can take an enum like so:

class BlogPost
{
    private Status $m_status;

    public function __construct(Status $status) 
    {
        $this->m_status = $status;
    }
}

Create and pass the status enum like so:

$post = new BlogPost(Status::DRAFT);

Enum Methods

One can define and use methods on an enum, although I'm not sure this is generally adviseable.

The following method will return a colour based on the status. E.g.

enum Status
{
    case DRAFT;
    case PUBLISHED;
    case ARCHIVED;

    /**
     * Return a the colour to represent the status.
     * @return string - the name of the colour.
     */
    public function colour(): string
    {
        $colour = match($this) {
            self::DRAFT => "grey",   
            self::PUBLISHED => "green",   
            self::ARCHIVED => "red"
        };

        return $colour;
    }
}

Documentation for match().

... and an example of this would be:

$status = Status::DRAFT;
$colour = $status->colour();

Enum Interfaces

Since enums can have methods, it makes sense that they can also implement interfaces which would specify required public methods that must be implemented.

Backed/Typed Enums

One can declare that the values for enums are either strings or integers like so:

enum Status: string
{
    case DRAFT = "draft";
    case PUBLISHED = "published";
    case ARCHIVED = "archived";
}

...or:

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

If specifying a type, then all cases need to have a number/string assignment of the same type.

Retrieve Enum Value

One can get the value of an enum using the value public property like so:

print Status::PUBLISHED->value; // 2

Create Enum From Value

Likewise, one can create the enum from the numerical value (good for when converting from database row).

$row = $result->fetch_assoc();
$status = Status::from($row['status']); // assuming $row['status'] is the number 2

TryFrom Value

The from() method will throw an exception if the value passed is not recognized by the enum. If you would prefer a null to be returned in such a scenario, then use tryFrom() instead.

$status = Status::tryFrom(100); // $status is null because the status enum does not have a case for 100.

Serialize, Unserialize, and Json Encode

Enums have built in serialize() and unserialize() methods. Likewize, if you used backed enums, json_encode will automatically return the typed value.

Cases() method - Get Array Of Cases

If you want to get an array of the cases for an enum, call the cases static method.

Status::cases()

Comparison

One can compare enums against each other like so:

if ($post1->getStatus() === $post2->getStatus())
{
    // do something.
}

Array Keys  

Due to the fact that enums are objects, you cannot use them as array keys, which may likely change in the future. However, you could do the following:

$list = [
    $myEnum->value => "foo",
    $mySecondEnum->value => "bar",
];
Last updated: 29th November 2021
First published: 29th November 2021