能否在 PHP 中动态创建实例属性?

2022-08-30 09:40:44

有没有办法动态创建所有实例属性?例如,我希望能够在构造函数中生成所有属性,并且在类实例化后仍然能够访问它们,如下所示:。请注意,我想单独访问属性,而不是使用数组;这是一个我不想要的例子:$object->property

class Thing {
    public $properties;
    function __construct(array $props=array()) {
        $this->properties = $props;
    }
}
$foo = new Thing(array('bar' => 'baz');
# I don't want to have to do this:
$foo->properties['bar'];
# I want to do this:
//$foo->bar;

更具体地说,当我处理具有大量属性的类时,我希望能够选择数据库中的所有列(表示属性)并从中创建实例属性。每个列值应存储在单独的实例属性中。


答案 1

差不多吧。有一些神奇的方法允许您挂接自己的代码,以便在运行时实现类行为:

class foo {
  public function __get($name) {
    return('dynamic!');
  }
  public function __set($name, $value) {
    $this->internalData[$name] = $value;
  }
}

这是动态 getter 和 setter 方法的一个示例,它允许您在访问对象属性时执行行为。例如

print(new foo()->someProperty);

在这种情况下,将打印“dynamic!”,您还可以为任意命名的属性分配一个值,在这种情况下,__set()方法被静默调用。__call($name, $params) 方法对对象方法调用执行相同的操作。在特殊情况下非常有用。但大多数时候,你会得到:

class foo {
  public function __construct() {
    foreach(getSomeDataArray() as $k => $value)
      $this->{$k} = $value;
  }
}

...因为大多数情况下,您所需要的只是将数组的内容转储到相应命名的类字段中一次,或者至少在执行路径中非常显式的点。因此,除非您真的需要动态行为,否则请使用最后一个示例用数据填充对象。

这称为重载 http://php.net/manual/en/language.oop5.overloading.php


答案 2

这完全取决于你想要什么。你能动态修改吗?没有。但是,是否可以动态创建对象属性,就像在该类的一个特定实例中一样?是的。

class Test
{
    public function __construct($x)
    {
        $this->{$x} = "dynamic";
    }
}

$a = new Test("bar");
print $a->bar;

输出:

动态

因此,在构造函数中动态创建了一个名为“bar”的对象属性。


推荐