我有一个模型,具有许多属性(属性)。其中之一form_fields
存储JSON,以使用验证填充动态表单字段。喜欢:
// ./protected/models/FormBuilder.php
/**
* FormBuilder AR model class with dynamic field building capabilities
*
* @property integer $id
* @property string $form_title
* @property string $form_fields Form fields definitions stored as JSON String
*/
class FormBuilder extends CActiveRecord {
public function init_form_model() {
$dynamic_fields = CJSON::decode($this->form_fields);
foreach($dynamic_fields as $field => $props) {
// Neither this
$this->$field = '';
// nor this working!!!
$this->setAttribute($field, '');
}
}
/* other methods as it is */
}
// ./protected/controllers/FormBuilderController.php
class FormBuilderController extends CController {
// ...
public function actionServing($form_id) {
$form = FormBuilder::models()->findByPk($form_id);
$form->init_form_model();
$this->render('dyn_frm', ['form' => $form]);
}
// ...
}
在方法FormBuilder->init_form_model()
中,引发异常。未定义[[Property“ FormBuilder.first_name”属性。。
我也尝试使用PHP的ReflectionClass设置新属性,但收到相同的错误消息。
因此,我打开了Yii的CActiveRecord.php源代码,并复制了其中的四个魔术方法,并在我的模型类中继承,如下所示:
/**
* PHP getter magic method.
* This method is overridden so that AR attributes can be accessed like properties.
* @param string $name property name
* @return mixed property value
* @see getAttribute
*/
public function __get($name) {
if (isset($this->form_fields[$name])) {
if (isset($this->form_fields[$name]['value'])) {
return $this->form_fields[$name]['value'];
}
return null;
}
return parent::__get($name);
}
/**
* PHP setter magic method.
* This method is overridden so that AR attributes can be accessed like properties.
* @param string $name property name
* @param mixed $value property value
* @throws CException
*/
public function __set($name, $value) {
if (isset($this->form_fields[$name])) {
$this->form_fields[$name]['value'] = $value;
} else {
parent::__set($name, $value);
}
}
/**
* Checks if a property value is null.
* This method overrides the parent implementation by checking
* if the named attribute is null or not.
* @param string $name the property name or the event name
* @return boolean whether the property value is null
*/
public function __isset($name) {
if (isset($this->form_fields[$name])) {
return true;
}
return parent::__isset($name);
}
/**
* Sets a component property to be null.
* This method overrides the parent implementation by clearing
* the specified attribute value.
* @param string $name the property name or the event name
* @throws CException
*/
public function __unset($name) {
if (isset($this->form_fields[$name])) {
unset($this->form_fields[$name]);
return;
}
parent::__unset($name);
}
在此处找到类似的问题,答案: