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?
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)
{
if($this->setAttribute($name,$value)===false)
{
if(isset($this->getMetaData()->relations[$name]))
$this->_related[$name]=$value;
else
parent::__set($name,$value);
}
}
public function setAttribute($name,$value)
{
if(property_exists($this,$name))
$this->$name=$value;
else if(isset($this->getMetaData()->columns[$name]))
$this->_attributes[$name]=$value;
else
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)
{
$setter='set'.$name;
if(method_exists($this,$setter))
return $this->$setter($value);
else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
{
// duplicating getEventHandlers() here for performance
$name=strtolower($name);
if(!isset($this->_e[$name]))
$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;
}
}
if(method_exists($this,'get'.$name))
throw new CException(Yii::t('yii','Property "{class}.{property}" is read only.',
array('{class}'=>get_class($this), '{property}'=>$name)));
else
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?
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;