Php enums

Written on 2021-02-17

PHP 8.1 introduces native enum support, a powerful feature that allows developers to define type-safe enumerated values. This guide covers everything you need to know about PHP enums, including syntax, backed enums, methods, interfaces, and practical use cases.

If you're upgrading to PHP 8.1 or want to modernize your PHP codebase, understanding enums is essential. Subscribe to my newsletter for more PHP tutorials and updates.

What Are PHP Enums?

PHP enums (enumerations) are a special data type that allows you to define a fixed set of constant values. Here's a basic PHP enum example:

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

Why Use PHP Enums?

The main benefit of PHP enums is type safety. Instead of using string or integer constants, you can type-hint enum values in your code:

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

Using an enum in your PHP code is straightforward:

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

This provides IDE autocomplete support, prevents typos, and makes your code more maintainable. Now let's explore the advanced features of PHP enums.

PHP Enum Methods

Enums can define methods, just like classes. This is a powerful feature that enables you to encapsulate behavior within your enum, especially when combined with PHP 8's match expression:

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

You can call enum methods directly on enum cases:

$status = Status::ARCHIVED;

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

Static Methods in PHP Enums

Enums support static methods, which can be useful for factory patterns:

enum Status
{
    // …

    public static function make(): Status
    {
        // …
    }
}

You can also use the self keyword to reference the enum type:

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

PHP Enum Interfaces

PHP enums can implement interfaces, just like regular classes. This allows you to enforce that enums provide specific methods:

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

Backed Enums in PHP

Backed enums allow you to assign scalar values (string or int) to enum cases. This is particularly useful when storing enums in databases or working with APIs.

String-Backed Enums

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

Integer-Backed Enums

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

The type declaration (: string or : int) indicates the backing type. Only string and int are supported as backing types in PHP 8.1.

Important: When using backed enums, all cases must have a value. You cannot mix backed and pure enum cases. Enums without backing values are called "pure enums".

Combining Backed Enums with Interfaces

When using both backed enums and interfaces, the backing type must come directly after the enum name, before the implements keyword:

enum Status: string implements HasColor
{
    case DRAFT = 'draft';
    case PUBLISHED = 'published';
    case ARCHIVED = 'archived';

    // …
}

How to Serialize PHP Enums

Backed enums provide built-in serialization support, making it easy to store and retrieve enum values from databases or APIs.

Accessing Enum Values

You can access the backing value using the readonly value property:

$value = Status::PUBLISHED->value; // 2

Deserializing Enums from Values

Use the from() method to create an enum instance from a backing value:

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

For safer deserialization, use tryFrom() which returns null for invalid values instead of throwing an exception:

$status = Status::from('unknown'); // ValueError exception
$status = Status::tryFrom('unknown'); // null

JSON and Native Serialization

PHP enums work with built-in serialization functions:

  • serialize() and unserialize() work with enums
  • json_encode() returns the backing value for backed enums
  • You can implement JsonSerializable to customize JSON output

How to List All PHP Enum Cases

The static cases() method returns an array of all enum cases:

Status::cases();

/* [
    Status::DRAFT,
    Status::PUBLISHED,
    Status::ARCHIVED
] */

This array contains actual enum objects, so you can iterate and call methods:

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

PHP Enums Are Objects

PHP enum cases are represented as singleton objects. This enables identity comparisons and type checking:

$statusA = Status::PENDING;
$statusB = Status::PENDING;
$statusC = Status::ARCHIVED;

$statusA === $statusB; // true
$statusA === $statusC; // false
$statusC instanceof Status; // true

Enum Limitations: Array Keys

Currently, you cannot use enum objects as array keys:

$list = [
    Status::DRAFT => 'draft', // Error
    // …
];

There is an RFC to add this functionality in future PHP versions.

Workaround: Use enums as keys in SplObjectStorage or WeakMap collections.

PHP Enum Traits

Enums can use traits for code reuse, with some restrictions:

  • Cannot override built-in enum methods
  • Cannot contain properties (properties are prohibited in enums)
  • Can only add methods and use trait methods

Reflection and Attributes for PHP Enums

PHP 8.1 adds several reflection classes for working with enums:

  • ReflectionEnum - For enum reflection
  • ReflectionEnumUnitCase - For pure enum cases
  • ReflectionEnumBackedCase - For backed enum cases
  • enum_exists() - Function to check if an enum exists

Using Attributes with Enums

Enums support PHP 8 attributes on both the enum itself and individual cases:

#[SomeAttribute]
enum Status
{
    #[CaseAttribute]
    case DRAFT;
}

Note that the TARGET_CLASS attribute target includes enums.

The name Property

All enums have a readonly $enum->name property that returns the case name as a string. This is primarily intended for debugging purposes.

Join over 14k subscribers on my mailing list: I write about PHP, programming, and keep you up to date about what's happening on this blog. You can subscribe by sending an email to brendt@stitcher.io.

Conclusion

PHP 8.1 enums provide a powerful, type-safe way to work with fixed sets of values. Whether you're using pure enums for simple type safety or backed enums for database storage, this feature helps write cleaner, more maintainable PHP code.

Key takeaways:

  • Enums provide type safety and IDE support
  • Backed enums (string/int) enable database serialization
  • Enums can have methods, implement interfaces, and use traits
  • Use cases() to list all values and from()/tryFrom() for deserialization

Ready to upgrade? Check out the complete PHP 8.1 feature list and start using enums in your projects today.

Things I wish I knew when I started programming

Things I wish I knew when I started programming cover image

This is my newest book aimed at programmers of any skill level. This book isn't about patterns, principles, or best practices; there's actually barely any code in it. It's about the many things I've learned along the way being a professional programmer, and about the many, many mistakes I made along that way as well. It's what I wish someone would have told me years ago, and I hope it might inspire you.

Read more

Comments

Loading…
No comments yet, be the first!
Noticed a tpyo? You can submit a PR to fix it.
Home RSS Newsletter Discord © 2026 stitcher.io Login