PHP RFC

Voting for the PHP Enums RFC have just ended today with 44 Yes and & No, So Enumerations will be finally part of the next PHP 8.1. PHP Enumerations RFC was proposed is finally here thanks to the work of Larry Garfield and Ilija Tovilo.

The scope of the RFC is limited to unit enumerations, that is, enumerations that are themselves a value, rather than simply a fancy syntax for a primitive constant, and do not include additional associated information. 

php enums

 This capability offers greatly expanded support for data modeling, custom type definitions, and monad-style behavior. Enums enable the modeling technique of make invalid states unrepresentable, which leads to more robust code with less need for exhaustive testing.

A new PHP language construct is introduced with this RFC : enum. They are similar to classes and share the same namespaces as classes, interfaces, and traits. They are also autoloadable the same way. An Enum defines a new type, which has a fixed, limited number of possible legal values.

Getting started with PHP Enums

An example of PHP Enum could be :

enum Levels {
  case Admin;
  case Author;
  case Contributor;
  case Subscriber;
}

We defined here a collection of constant values, so if we define class users with it we can have something like :

class Users
{
    public function __construct(
        public Levels $level, 
    ) {}
}

If we need to access list of users by permission level we can use something like :

function get_users(Levels $level) { ... }
 
$val = Levels::Subscriber;
 
get_users($val);        // OK
get_users(Levels::Author); // OK
pick_a_card('Admin');    // TypeError: get_users(): Argument #1 ($level) must be of type Levels, string given

Enumerated Methods

Enums may contain methods, and may implement interfaces. If an Enum implements an interface, then any type check for that interface will also accept all cases of that Enum. For example :

enum Levels
{
    case Admin;
    case Author;
    case Contributor;
    case Subscriber;
    
    public function color(): string
    {
        return match($this) 
        {
            Status::Admin => 'red',   
            Status::Author => 'green',   
            Status::Contributor => 'orange',   
            Status::Subscriber => 'grey',   
        };
    }
}

$status = Status::Contributor;

$status->color(); // 'orange'

More Enumerated Features

Enumerations may also have static methods. The use for static methods on the enumeration itself is primarily for alternative constructors. It  may include constants, which may be public, private, or protected, although in practice private and protected are equivalent as inheritance is not allowed.

Enumerations may leverage traits, which will behave the same as on classes. The caveat is that traits used in an enum must not contain properties. They may only include methods and static methods. A trait with properties will result in a fatal error.

Because cases are represented as constants on the enum itself, they may be used as static values in most constant expressions: property defaults, static variable defaults, parameter defaults, global and class constant values. They may not be used in other enum case values due to implementation complexity. (That restriction may be lifted in the future, but since they can be used by constants on an enum it is not a significant limitation.)

However, implicit magic method calls such as ArrayAccess on enums are not allowed in static or constant definitions as we cannot absolutely guarantee that the resulting value is deterministic or that the method invocation is free of side effects. Function calls, method calls, and property access continue to be invalid operations in constant expressions.

Enum Sample

A simple application of PHP Enums could be in SQL queries for example :

enum SortOrder {
  case ASC;
  case DESC;
}
 
function query($fields, $filter, SortOrder $order = SortOrder::ASC) { ... }

The query() function can now proceed safe in the knowledge that $order is guaranteed to be either SortOrder::ASC or SortOrder::DESC. Any other value would have resulted in a TypeError, so no further error checking or testing is needed.

Overall, PHP Enums seems to be one of the hottest features in PHP 8.1, it will make code not only more robust, but also more secure with less efforts. More information about PHP Enumerations RFC at https://wiki.php.net/rfc/enumerations

LEAVE A REPLY

Please enter your comment!
Please enter your name here