Магический метод PHP Enums `__toString`

Мне интересно, почему невозможно предоставить реализация для enum.

IDE говорит: «Enum не может включать '__toString'». Однако это было первое, о чем я подумал, когда создал enum. Раньше я использовал объекты-значения, инкапсулирующие строки в моем коде, которые при необходимости использовали преобразование строк. Теперь я хотел бы перенести их в перечисления, но они сопротивляются.

      #[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 ответа

Я думаю, вам не следует использовать Enum, если вы хотите использовать его какconstв обычном классе. Вместо этого рассмотрите возможность создания абстрактного класса следующим образом:

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

Помимо правильного использования Enum, в вашем случае вы можете использовать:

      echo SaveKlinesFromApiQueue::DEFAULT->name;

Result: "DEFAULT"

или

      echo SaveKlinesFromApiQueue::DEFAULT->value;

Result: "save_klines_from_api_queue"

Как упоминает Крис, магические методы запрещены.

Для 2 наиболее (?) распространенных вариантов использования:

Чтобы получить строковое значение одного, вы можете просто использовать ->value.

Если вам нужны строковые значения всех из них, просто добавьте цикл в метод:

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

Для простых перечислений значений используйте «const» вместо «case»:

      enum SaveKlinesFromApiQueue: string {
    const DEFAULT = 'save_klines_from_api_queue';
    const PRIORITY = 'save_klines_from_api_priority_queue';
}

echo SaveKlinesFromApiQueue::DEFAULT;

Реализация JsonSerializable работает, если ваш вариант использования включает преобразование свойства перечисления в 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();
    }
}
Другие вопросы по тегам