Часто ли вам приходилось сожалеть о том, что в PHP нет перечислений как таковых?
Да, кто-то обходился конвенцией именования и получалось нечто вроде:
Или нечто вроде:
Но оба подхода имеют существенные недостатки:
Под катом предлагаю решение без вышеописанных недостатков…
Это базовый класс для перечислений. При работе нам надо будет только подключить его и в дальнейшем можно о нем забыть.
Ну а что бы реализовать сами перечисления, нам необходимо написать подобную структуру:
И теперь что бы обращаться к константному значению и использовать type hinting нам надо создать объект из данного класса, передав в конструктор имя необходимой константы:
З.Ы. А вот когда выйдет релиз PHP5.3, то можно будет добавить к класс Enum метод:
который будет возвращать все пары: ключ-значение
оригинал
Да, кто-то обходился конвенцией именования и получалось нечто вроде:
define( 'COLOR_RED', 'F00' ); define( 'COLOR_GREEN', '0F0' ); define( 'COLOR_BLUE', '00F' );
Или нечто вроде:
// данную переменную ЗАПРЕЩЕНО модифицировать $colors = array( 'red' => 'F00', 'green' => '0F0', 'blue' => '00F', );
Но оба подхода имеют существенные недостатки:
- В первом случае члены перечисления не образуют явной группировки
- Во втором случае есть риск что переменная будет изменена
- И в обоих этих случаях мы не можем делать проверку на тип переменной (type hinting)
Под катом предлагаю решение без вышеописанных недостатков…
abstract class Enum { private $current_val; final public function __construct( $type ) { $class_name = get_class( $this ); $type = strtoupper( $type ); if ( constant( "{$class_name}::{$type}" ) === NULL ) { throw new Enum_Exception( 'Свойства '.$type.' в перечислении '.$class_name.' не найдено.' ); } $this->current_val = constant( "{$class_name}::{$type}" ); } final public function __toString() { return $this->current_val; } } class Enum_Exception extends Exception {}
Это базовый класс для перечислений. При работе нам надо будет только подключить его и в дальнейшем можно о нем забыть.
Ну а что бы реализовать сами перечисления, нам необходимо написать подобную структуру:
class Enum_Colors extends Enum { const RED = 'F00'; const GREEN = '0F0'; const BLUE = '00F'; }
И теперь что бы обращаться к константному значению и использовать type hinting нам надо создать объект из данного класса, передав в конструктор имя необходимой константы:
function setColor( Enum_Colors $color ) { echo $color; } setColor( new Enum_Colors( 'GREEN' ) ); // will pass setColor( '0F0' ); // won't pass Enum_Colors::RED == new Enum_Colors( 'GREEN' ); // FALSE Enum_Colors::RED == new Enum_Colors( 'RED' ); // TRUE
З.Ы. А вот когда выйдет релиз PHP5.3, то можно будет добавить к класс Enum метод:
public static method asArray() {}
который будет возвращать все пары: ключ-значение
оригинал