Часто ли вам приходилось сожалеть о том, что в 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() {}
который будет возвращать все пары: ключ-значение
оригинал
