Yii 1.1: Managing constants easily

8 followers

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 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;
    }

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 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;
    }
 
}

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 static function getStatuses() {
        return self::getConstants('STATUS_',__CLASS__);
    }
    public static 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.

Total 4 comments

#6284 report it
briiC.lv at 2011/12/25 04:40am
easier != better

@johnnyma - i was using params.php file before writing getConstants() function, but i found it not so great:

  1. 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.

  2. 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.

#6270 report it
Johnny at 2011/12/23 04:19am
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. :)

#6075 report it
briiC.lv at 2011/12/10 03:46am
Changed "public function" to "public static function"

Thanks twisted1919 for pointing this out!

#6071 report it
twisted1919 at 2011/12/09 06:04pm
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.

Leave a comment

Please to leave your comment.

Write new article