Create property inside a model

Currently there’s no way to create a property inside a model method:

$this->$dynamicVar = 'some value';

This is because the setter is overridden by CActiveRecord. I need this to allow custom fields inside the register model such as name, age etc etc whatever the admin needs from new users so it’s a dynamic value all the time. Has anyone encountered this problem?

I’m not really sure I understand you correctly, but if I do, you could try:

$this->__set($dynamicVar, 'some value');

If that’s not what you mean, please describe your problem in a little more detail :)

That’s what I mean allright. The problem is that this magic function is overridden by CActiveRecord which of course is extended by my model:

public function __set($name,$value)










public function setAttribute($name,$value)




	else if(isset($this->getMetaData()->columns[$name]))



		return false;

	return true;


As you can see, setAttribute returns false when you try to create a model property on the fly because property_exists($this,$name) returns false isset($this->getMetaData()->columns[$name]) returns false as well so the magic function __set does not set the property. So the function calls parent::__set($name,$value); so it goes to this:

public function __set($name,$value)




		return $this->$setter($value);

	else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))


		// duplicating getEventHandlers() here for performance



			$this->_e[$name]=new CList;

		return $this->_e[$name]->add($value);


	else if(is_array($this->_m))


		foreach($this->_m as $object)


			if($object->getEnabled() && (property_exists($object,$name) || $object->canSetProperty($name)))

				return $object->$name=$value;




		throw new CException(Yii::t('yii','Property "{class}.{property}" is read only.',

			array('{class}'=>get_class($this), '{property}'=>$name)));


		throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',

			array('{class}'=>get_class($this), '{property}'=>$name)));


The conclusion is, we can’t create properties inside a model. Should I create my own setter for this model? Is this safe?

I think I’d try something like this:

private $dynamicAttributes = array();

public function __set($attr, $value) {

    if(parent::__set($attr, $value)===false) {

        $this->dynamicAttributes[$attr] = $value;



public function __get($attr) {

    return $this->__isset($attr) ? parent::__get($attr) : $this->dynamicAttributes[$attr];


Would that work for you?

Thanks, I appreciate it. Here’s what I ended up with:

	public function __get ( $name ) {

		if ( isset ( $this->dynAttributes [ $name ] ) ) return $this->dynAttributes [ $name ];


			return parent::__get ( $name );


	public function __set ( $attr, $value ) {

		try {

			parent::__set ( $attr, $value );

		} catch ( CException $e ) {

			$this->dynAttributes [ $attr ] = $value;



I use a try catch because CComponent throws an exception if __set fails.

Cool, that looks fine :)


private $somevalue;

in model class def this works for me:

function setSomevalue($value) {

  $this->somevalue = $value;


function getSomevalue($value) {

  return $this->somevalue;


That’s because you already declared it in the class: private $somevalue;

I retrieve those fields based on admin’s settings so I can’t declare them. I must create them on the fly. Try setting $this->somevalue = $value; without having it declared previously using private $somevalue;

Check this out:

Understanding Virtual Attributes and get/set methods

if you create a method like this in your model class:

class Person extends CActiveRecord {

   public function getFullName()


      return $this->firstname . " " . $this->lastname;




You can call it like normal ways:

// in a view somewhere

echo $form->dropDownList($model, 'personid',

    CHtml::listData( Person::model()->findAll(), 'id', 'fullname' )


$x = $model->fullname;

$x = $model->getFullname();        // same thing