【问题标题】:Declare class property at runtime, in Yii2在运行时声明类属性,在 Yii2
【发布时间】:2015-06-22 13:27:44
【问题描述】:

我有一个从 Yii2 的 Model 扩展而来的类,我需要在构造函数中声明一个类公共属性,但我遇到了问题。

当我打电话时

class Test extends \yii\base\Model {
    public function __constructor() {
        $test = "test_prop";
        $this->{$test} = null; // create $this->test_prop;
    }
}

Yii 试图调用,据我了解,这个属性的 getter 方法,当然不存在,所以我点击了this 异常。

另外,当我实际执行$this->{$test} = null; 时,this 方法被调用。

我的问题是:有没有办法以另一种方式声明一个类的公共属性?也许是一些反射技巧?

【问题讨论】:

    标签: php reflection yii2


    【解决方案1】:

    您可以覆盖 getter/setter,例如:

    class Test extends \yii\base\Model
    {
        private $_attributes = ['test_prop' => null];
    
        public function __get($name)
        {
            if (array_key_exists($name, $this->_attributes))
                return $this->_attributes[$name];
    
            return parent::__get($name);
        }
    
        public function __set($name, $value)
        {
            if (array_key_exists($name, $this->_attributes))
                $this->_attributes[$name] = $value;
    
            else parent::__set($name, $value);
        }
    }
    

    你也可以创建一个行为...

    【讨论】:

    • 我认为 attributes 在内部使用与我的方式相同的 setter 和 getter。
    • 好的,谢谢!您的解决方案看起来与我从 Yii 的一位开发人员那里得到的答案一模一样 :)
    【解决方案2】:

    尝试在init方法中设置变量。

    像这样:

    public function init() {
      $test = "test_prop";
      $this->{$test} = null; // create $this->test_prop;
      parent::init();
    }
    

    【讨论】:

    • 没错,这并不能解决任何问题,它只是改变了问题的根源。
    • 等等,这是模特。你在课堂上声明了变量 $test_prop 吗?像这样: public $test_prop
    【解决方案3】:

    好的,我 received help 来自 Yii 的一位开发人员。答案如下:

    class Test extends Model {
        private $dynamicFields;
    
        public function __construct() {
            $this->dynamicFields = generate_array_of_dynamic_values();
        }
    
        public function __set($name, $value) {
            if (in_array($name, $this->dynamicFields)) {
                $this->dynamicFields[$name] = $value;
            } else {
                parent::__set($name, $value);
            }
        }
    
        public function __get($name) {
            if (in_array($name, $this->dynamicFields)) {
                return $this->dynamicFields[$name];
            } else {
                return parent::__get($name);
            }
        }
    
    }
    

    请注意,我使用的是in_array 而不是array_key_exists,因为dynamicFields 数组是普通数组,而不是关联数组。

    编辑:这实际上是错误的。请参阅我接受的答案。

    【讨论】:

    • 你错了in_array$dynamicFields 是关联的:$this->dynamicFields[$name] = $value;
    猜你喜欢
    • 1970-01-01
    • 2011-04-22
    • 2016-11-11
    • 2010-12-10
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多