Php enums
Written on 2021-02-17PHP 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()andunserialize()work with enumsjson_encode()returns the backing value for backed enums- You can implement
JsonSerializableto 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 reflectionReflectionEnumUnitCase- For pure enum casesReflectionEnumBackedCase- For backed enum casesenum_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 andfrom()/tryFrom()for deserialization
Ready to upgrade? Check out the complete PHP 8.1 feature list and start using enums in your projects today.