PHP Enums `__toString` magic method

Viewed 5734

I am wondering why it is not possible to provide an __toString implementation for enum.

IDE says "Enum may not include '__toString'". However it was the first thing I thought about once I created enum. Previously I used Value Objects encapsulating strings in my code, which utilized string casting when necessary. Now I would like to migrate 'em into enums, but those resist.

#[Immutable]
enum SaveKlinesFromApiQueue: string
{
    case DEFAULT = 'save_klines_from_api_queue';
    case PRIORITY = 'save_klines_from_api_priority_queue';

    public function __toString(): string
    {
        return $this->value;
    }
}
4 Answers

I think you shouldn't use Enum if you want to use it like const in a regular class. Consider creating an abstract class instead like this:

abstract class SaveKlinesFromApiQueue
{
    public const DEFAULT = 'save_klines_from_api_queue';
    public const PRIORITY = 'save_klines_from_api_priority_queue';
}

Aside from the correct use of Enum, in your case you can use:

echo SaveKlinesFromApiQueue::DEFAULT->name;

Result: "DEFAULT"

or

echo SaveKlinesFromApiQueue::DEFAULT->value;

Result: "save_klines_from_api_queue"

As chris mentions, magic methods are not allowed.

For the 2 most(?) common usecases:

To get the string value of a single one, you can just use ->value.

If you want the string values of all of them, just add a loop in a method:

    public static function strings(): array
    {
        $strings = [];
        foreach(self::cases() as $case) {
            $strings[] = $case->value;
        }
        return $strings;
    }

Implementing JsonSerializable works if your use-case involves converting an enum property to json.

enum ParameterTypeEnum implements \JsonSerializable
{
    case QUERY;
    case COOKIE;
    case HEADER;
    case PATH;

    public function getType(): string
    {
        return match($this) {
            ParameterTypeEnum::QUERY => 'query',
            ParameterTypeEnum::COOKIE => 'cookie',
            ParameterTypeEnum::HEADER => 'header',
            ParameterTypeEnum::PATH => 'path',
        };
    }

    public function jsonSerialize(): mixed
    {
        return $this->getType();
    }
}

Do it your self without of magic ! ;-) We have PHP 8.1 now.

enum DataType: string {

    case ACCEPTED = "accepted";
    case WITH_ERRORS = "with errore";
    case DONE = "done";
    case FAILED ='failed';

    public function toString(): string {
      return match($this){
        self::ACCEPTED => 'Accepted',
        self::WITH_ERRORS => 'With Errors',
        self::DONE  => 'Done',
        self::FAILED  => 'Failed',
        default => '',
      };
    }
}

OutPrint:> print(DataType::DONE->toString());

Related