PHP 8.1 introduced Enums, a new data structure developers can leverage for better typing and readability.
Enums in short
Enums allow defining a short list of values:
enum PostStatus: string
{
case Published = 'publish';
case Draft = 'draft';
case Expired = 'expired';
case Future = 'scheduled';
}
I strongly recommend the blog post by stitcher.io to understand the technique.
I'd like to focus on the why and how I understand this new type.
Enums vs. constants
Dev teams often use contants to define such statuses (see example above):
class PostStatus {
const PUBLISHED = 'publish';
const DRAFT = 'draft';
const EXPIRED = 'expired';
const FUTURE = 'scheduled';
}
While it can totally work, it's prone to human errors and there's now a better way to implement the same feature with better typing: PHP enums.
Mistakes like the following may happen with the old syntax:
class PostStatuses {
const PUBLISHED = 'publish';
const DRAFT = 'publish';
}
With PHP enums, it's impossible to attribute the same value to two different cases.
However, that's not the only benefit. You can use the following to ensure you are processing a valid status:
public function myHelper(PostStatus $status)
{
// some code
}
This way, you don't have to implement a defensive strategy by yourself to check whether your variable is a valid status every time you need it.
It's now built-in, so you don't have to throw an error manually.
Catch them all
No need to implement any custom method to list all valid statuses:
PostStatus::cases();
It's now built-in, and you can get all cases with the static cases()
.
Enums are final and values are objects
According to stitcher.io, enum values are singleton objects, so you can't instanciate them, but any value is an instance of the Enum:
$draft = PostStatus::DRAFT;
$draft instanceof PostStatus; // true
It's worth mentioning PHP enums are final, so you cannot extend them. They aren't meant to hold any state, so you won't be able to use most magic methods, but all of that's fine, because the purpose of PHP enums is type safety.
Wrap up
This new PHP type is pretty cool. In my experience, it's very convenient to use and test.