You are viewing revision #1 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version.
Problem ¶
For time to time i have models with constants (basicly status constants) which i use in diferent places and if these constant changes, i have to change mentions of constant in code elsewhere.
getConstants() ¶
For this small problem i am using function getConstants().
public 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;
}
Usage example ¶
To add this function for every ActiveRecord class extend CActiveRecord
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 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;
}
}
After that extend new models with ActiveRecord class (not 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';
//...
}
and use self::getConstants() in models rules definitions, methods or outside model
class Media extends ActiveRecord {
//..
public function rules()
{
return array(
array('type', 'in','range' => self::getConstants('TYPE_',__CLASS__)),
);
}
//..
public function getStatuses() {
return self::getConstants('STATUS_',__CLASS__);
}
public function getTypes() {
return self::getConstants('TYPE_',__CLASS__);
}
}
Somewhere else
print_r( Media::getConstants('STATUS_','Media') );
//or create Media method and use simplified
print_r( Media::getStatuses() );
Conclusion ¶
Of course you don't need this if you have model with only two constants. It's more handy if you got tons of them.
Thanks and please leave comment if you have something to say.
Nice, but...
self::getConstants(); on a public function which isn't declared as static ?
Change it to either "public static function" or reference it via $this.
Changed "public function" to "public static function"
Thanks twisted1919 for pointing this out!
try a easier way
Try to use /protected/config/params.php to keep the constants, I think it would be much simple. Also, in this way you could get your constants everywhere of your application. :)
easier != better
@johnnyma - i was using params.php file before writing getConstants() function, but i found it not so great:
it's bunch of variables defined in params() that is not targeted to all app, but only one or some models (or one scenario). So spliting varibales/constants to several scopes (php classes) you know where to find exactly and which constants are related.
you lose autocomplete of your editor ( http://bit.ly/swIs74 - here isn't php but you get the idea ).
I will repeat myself: "Of course you don't need this if you have model with only two constants. It's more handy if you got tons of them." - so maybe you not in the point where you have many constants to manage.
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.