TL;DR
The basic and backed enums of this RFC are a nice implementation of enums in PHP, but in its current form it simply does too much.
Foreword
Yesterday Brendt from Spatie posted a blog post about new things in PHP 8.1. The one things that caught my eye was enums and since I've been wanting them in PHP for quite a while now I got a bit excited to say the least.
Reading the RFC started good and well but the further I went, the more I disliked it.
Basic enums
The basic enum implementation of this RFC looks like so:
enum Suit {
case Hearts;
case Diamonds;
case Clubs;
case Spades;
}
Using case
to denote an enum value is slightly odd, but I'll take it. If it would be possible I believe it'd be better to omit this all together:
enum Suit {
Hearts;
Diamonds;
Clubs;
Spades;
}
Backed enums
Backed enums very much remind me of enums in TypeScript which are incredibly useful. Having this in PHP is very nice indeed.
enum Suit: string {
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
}
This feature alone would likely cause me to drop myclabs/php-enum as my enum implementation.
No mixing
Backed enums and Basic (or Pure) enums cannot be mixed together, so something like this is not allowed:
enum Suit: string {
case Hearts = 'H';
case Diamonds = 'D';
case Clubs;
case Spades;
}
I completely agree, otherwise it would just turn into a giant mess.
Enum methods
This is the point where the RFC lost me. I understand that having methods in an enum. Hell, in some cases I add a random()
method in enum classes made with myclabs/php-enum
. But that's usually as far as I'm willing to go.
If you need to add an interface or trait to an enum, why not just use a class instead?
The examples list extra information you can list with an enum, but doesn't that just beat the whole point of making enums to begin with?
Closing thoughts
I'd be incredibly happy if this RFC got accepted, enums are something that PHP can really use. Unfortunately, this implementation just does too much and it wouldn't surprise me if it got rejected on that basis.
However, should it be accepted, I'll be unlikely to use those enum methods.
Thanks for reading. This was my first proper post on this site and I'd like to improve my writing skills.
Any feedback on this post is greatly appreciated.
Top comments (5)
Yeah I agree with you. I had not read the whole RFC, just the first few points and thought it was great (kinda like class constants on steroids). After reading your post I went back to the RFC and read the whole thing... And either this tries to cover some very limited use cases, or I don't understand the point of Enums.
Enums are particularly useful when you need to enforce a subset of items that are valid.
Letβs say you have a button that can have 4 different colours. You could make those colours an enum. Or it can have 1 of 3 sizes, that could be an enum.
Or as in the RFC, a suit can be an enum.
Now you can also solve this by just using a string, but what do you do when someone puts in an invalid value? Youβd need to check for that. If you use an enum that check already happens during typechecking.
Yes I think get that part, that's what I called 'class constants on steroids'. What I would do in PHP 7 is something like :
With Enums it becomes a lot easier as you said.
But I don't need to put methods on my enums for that ! If I want a method that returns the shape or color of a suit I'll just create a
Suit
interface with a abstractsshape()
andcolor()
method and implement that method in aSpade
class.In the RFC they have an example where the color method uses a match statement to return the color and always return 'rectangle' as a shape. To me this kind of defeats the purpose of OOP.
Recently submitted an RFC related to enums.
I am curious what your thoughts are.
Since enums are objects I canβt see this being a good idea. Besides, you can just call
->value
on an enum instance and get the same result. I use this extensively adding translation capabilities to enums.