【问题标题】:Setting Dynamic Attribute to ModelClass将动态属性设置为 ModelClass
【发布时间】:2019-11-18 12:31:02
【问题描述】:

我有一个模型,有很多属性(属性)。其中之一 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() 抛出异常。 属性“FormBuilder.first_name”未定义。。

有什么解决办法吗?如何通过为模型类分配动态属性来进一步进行。 Yii 1.1 设置属性如果满足两个条件,首先如果类本身定义了属性,或者第二个 AR 模型的元数据有名为该属性的列被分配。

我也尝试使用 PHP 的 ReflectionClass 设置新属性,但收到相同的错误消息。

【问题讨论】:

    标签: php yii yii1.x


    【解决方案1】:

    嗯,我找到了解决方案来实现这一点。 PHP 的重载运行良好。

    于是,我打开了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);
    }
    

    在这里找到与答案类似的问题:

    Creating Yii FormModel objects (CFormModel) dynamically

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-16
      • 2019-02-24
      • 2015-10-06
      • 1970-01-01
      • 1970-01-01
      • 2011-02-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多