我正在尝试通过反射访问/更改类'Parent'的属性。
如果我在子节点上运行ReflectionClass :: getProperties(),它是否也返回父节点所有的属性?
如果没有,有没有办法使用Reflection访问父属性?
答案 0 :(得分:12)
我参加了这个快速测试。当您获得子类的属性时,看起来父类的私有属性是隐藏的。但是,如果您调用getParentClass()
然后调用getProperties()
,您将拥有缺少的私有道具集。
<?php
class Ford {
private $model;
protected $foo;
public $bar;
}
class Car extends Ford {
private $year;
}
$class = new ReflectionClass('Car');
var_dump($class->getProperties()); // First chunk of output
var_dump($class->getParentClass()->getProperties()); // Second chunk
输出(注意缺少私人道具Ford::model
):
array(3) {
[0]=>
&object(ReflectionProperty)#2 (2) {
["name"]=>
string(4) "year"
["class"]=>
string(3) "Car"
}
[1]=>
&object(ReflectionProperty)#3 (2) {
["name"]=>
string(3) "foo"
["class"]=>
string(4) "Ford"
}
[2]=>
&object(ReflectionProperty)#4 (2) {
["name"]=>
string(3) "bar"
["class"]=>
string(4) "Ford"
}
}
Second Chunk(包含Ford类的所有属性):
array(3) {
[0]=>
&object(ReflectionProperty)#3 (2) {
["name"]=>
string(5) "model"
["class"]=>
string(4) "Ford"
}
[1]=>
&object(ReflectionProperty)#2 (2) {
["name"]=>
string(3) "foo"
["class"]=>
string(4) "Ford"
}
[2]=>
&object(ReflectionProperty)#5 (2) {
["name"]=>
string(3) "bar"
["class"]=>
string(4) "Ford"
}
}
答案 1 :(得分:6)
虽然简洁,但公认的答案忽略了有许多祖先的儿童班的可能性。这是我用来实现此目的的实例方法:
public function getProperties() {
$properties = array();
try {
$rc = new \ReflectionClass($this);
do {
$rp = array();
/* @var $p \ReflectionProperty */
foreach ($rc->getProperties() as $p) {
$p->setAccessible(true);
$rp[$p->getName()] = $p->getValue($this);
}
$properties = array_merge($rp, $properties);
} while ($rc = $rc->getParentClass());
} catch (\ReflectionException $e) { }
return $properties;
}
它遍历层次结构,直到它到达根类,同时将每个父项的属性与其子项的属性合并(并且在默认情况下,仅使用在层次结构的最下部找到的默认值)。
答案 2 :(得分:0)
我认为您不会获得父私有属性,因为子类无法访问它们