> To the original question, there's two reasons that __toString() was > deliberately omitted from enums: > > 1. To discourage their use as "fancy strings". Enums are their own type, > independent of any other. Making them usable as 95% strings partially defeats > their purpose.
I disagree with the idea that we need to take this extreme of a stance when it comes to the notion of protecting the developer from themselves. There are a lot of really value use cases where it makes sense to have a string-backed enum . Not allowing developers to cast it to a string isn't doing anything but making people type $enum->value instead of (string)$enum -- so if someone wants to defeat their purpose this isn't stopping them. It is, however, making the language inconsistent because I literally have a enumeration defined by strings and there is literally no way to make PHP treat it like a string. This makes APIs sloppy imo because consider something like this: function foo(string|Stringable $bar) {} Because of these limitations this blows up into a much uglier thing in order accomplish what IMO should be a straightforward task: function fooThatWantsString(string|Stringable|UnitEnum $bar) { if(($bar instanceof UnitEnum) && !is_string($bar->value)) { throw InvalidArgumentException('This is exactly the sort of thing we are trying to get rid of with type hinting'); } else { $bar = $bar->value; } $bar = (string)$bar; } Of course, you could also pass $bar->value higher up the call stack but it's much cleaner IMO to let the function call be smart enough to typecast as necessary. What's the point of a Stringable interface if we can't actually implement __toString() for it? Note again we can implement JsonSerializable and nothing complains when enum serializes to a simple string. > 2. We still intend to add associated values to enums at some point (aka ADTs, > aka tagged unions), and... we're not really sure yet if that will impact > __toString() at all. It may, it may not, we don't know. So for now we're > keeping our options open by disallowing __toString(), in case it ends up > being needed for some ADT-related behavior in the future. __toString() should return a string, if an enum literally represents a string constant it makes zero sense for it to ever return anything but that string constant. I don't think this is something ADTs or tagged unions or anything of the sort should play a role in deciding. John