问题

我经常在不同的地方使用模型中的常量(基本状态常量),当常量改变时我不得不在使用每处它的代码中修改。

获取常量

为了解决这个问题我使用了一个方法 getConstants().




public static function getConstants($token,$objectClass) {
$tokenLen = strlen($token);

$reflection = new ReflectionClass($objectClass); //php built-in
$allConstants = $reflection->getConstants(); //constants as array

$tokenConstants = array();
foreach($allConstants as $name => $val) {
if ( substr($name,0,$tokenLen) != $token ) continue;
$tokenConstants[ $val ] = $val;
}

return $tokenConstants;
}


用法示例

为了给每个 ActiveRecord 类添加此方法,我们可以写个基类




class ActiveRecord extends CActiveRecord {

/*
Get class constants by token.
If you set constants with same prefix, like:
MY_STATUS_1
MY_STATUS_2
MY_STATUS_3

, you can get it by calling
Class::getConstants('MY');
or
Class::getConstants('MY_STATUS');
*/
public static function getConstants($token,$objectClass) {
$tokenLen = strlen($token);

$reflection = new ReflectionClass($objectClass); //php built-in
$allConstants = $reflection->getConstants(); //constants as array

$tokenConstants = array();
foreach($allConstants as $name => $val) {
if ( substr($name,0,$tokenLen) != $token ) continue;
$tokenConstants[ $val ] = $val;
}
return $tokenConstants;
}

}


然后所有的模型类都继承此类而不是 CActiveRecord




class Media extends ActiveRecord {
const TYPE_MUSIC = 'music';
const TYPE_VIDEO = 'video';
const TYPE_DOC = 'document';

const STATUS_ACTIVE = 'active';
const STATUS_REMOVED = 'removed';

//...
}


在模型规则,方法,或模型外使用 self::getConstants()




class Media extends ActiveRecord {
//..
public function rules()
{
return array(
array('type', 'in','range' => self::getConstants('TYPE_',__CLASS__)),
);
}
//..
public static function getStatuses() {
return self::getConstants('STATUS_',__CLASS__);
}
public static function getTypes() {
return self::getConstants('TYPE_',__CLASS__);
}

}


其他地方




print_r( Media::getConstants('STATUS_','Media') ); 
//or create Media method and use simplified
print_r( Media::getStatuses() );


小结

当然如果你的模型中只有两个常量你可以不使用它,但当你的模型中有大量常量时建议你使用。