ReflectionClass :: getProperties()是否也获得父级的属性?

时间:2012-03-28 18:37:52

标签: php reflection parent

我正在尝试通过反射访问/更改类'Parent'的属性。

如果我在子节点上运行ReflectionClass :: getProperties(),它是否也返回父节点所有的属性?

如果没有,有没有办法使用Reflection访问父属性?

3 个答案:

答案 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)

我认为您不会获得父私有属性,因为子类无法访问它们