Эмуляция перечислений Enum в PHP

Перечисления это удобно. Порой очень удобно. Они облегчают понимание кода, а так же его написание и сопровождение. По сути перечисления – это наборы связанных по смыслу констант.

По реализации – это класс. К сожалению в PHP нету типа , следовательно PHP программст не может получить все удобства Enum такие же, как, например, программист Java.
Но все же кое-что сделать можно.

Для чего оно надо?
Представьте, что у вас в коде есть какой-то набор связанных понятий, например типы какой-то сущности, или набор статусов. Так же может присутствовать соответствующий справочник в БД. И ваш код во многих местах зависит от этого набора. Например, по коду раскиданы проверки if вида:

С этим кодом есть две проблемы. Во первых – магические числа. Что означают эти вот 0, 3, awesomeType? Для начала можно было бы вынести эти значения в константы класса.
Но что если эти же значения используются в рамках модуля или проекта? Тогда мы можем вынести константы в отдельный класс, и назвать его MyModuleEnumTypes.

Отлично. Теперь у констант есть осмысленное имя и они повторно используемы.
Так же мы решили вторую проблему. Что если надо будет однажды сменить какое-то значение? Теперь оно меняется в одном месте в классе перечислении.

На этом можно было бы остановиться, но все же хочется добавить себе удобств, примерно таких как в Java. Каким образом мы можем получить массив значений перечисления? Имен ключей? Проверить значение на допустимость в конкретном перечислении?

Для всего этого я использую базовый класс BaseEnum.

Пройдемся по коду. Как мы видим, для доступа к списку констант используется ReflectionClass от get_called_class(), а не $this, такм образом мы берем класс перечисления наследника.
Далее сохраняем рез-т по имени класса в кеш. Остальные методы – это просто работа с полученным массивом.
Пример использования:

А что это за статическая переменная $available ?
Тут я добавил некоторую бузнес логику, которая позволяет определить, какие из значений перечисления активны, а какие нет.

На примере конкретного перечисления понятно:

Кроме всего списка, я опеределяю список доступных. Теперь если метод isValidValue(‘EUR’) выдаст TRUE, то метод isAvailable(‘EUR’) выдаст FALSE.

Вот так можно получить, хотя бы частично, функционал перечислений Enum в PHP и сделать свой код чище и понятнее.

Стоит еще сказать об полуофициальном расширении SPL Types. Устанавливается оно через PECL и псоле установки становится доступным класс SplEnum.
Почитать документацию можно по ссылке http://php.net//manual/ru/class.splenum.php.
На данный момент версия расширения 0.1.0 и лично я не стал использовать его в продакшене. Так же не известно, будет ли оно своевременно обновляться с версиями PHP.