在 Yii2 中在运行时声明 class 属性

Declare class property at runtime, in Yii2

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

当我打电话时

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 方法。

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

您可以覆盖 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);
    }
}

您还可以创建一个行为...

尝试在初始化方法中设置变量。

像这样:

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

好的,我 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 数组是普通数组,而不是关联数组。

编辑:这实际上是错误的。查看我接受的答案。