ReflectionClass :: getProperties()是否也获取父项的属性?

joh*_*ack 6 php reflection parent

我试图通过反射来访问/更改类'Parent'的属性.

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

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

Mik*_*e B 13

我做了这个快速测试.当您获得子类的属性时,看起来父类的私有属性是隐藏的.但是,如果你调用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
Run Code Online (Sandbox Code Playgroud)

输出(注意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"
  }
}
Run Code Online (Sandbox Code Playgroud)

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"
  }
}
Run Code Online (Sandbox Code Playgroud)


Nob*_*ift 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;
}
Run Code Online (Sandbox Code Playgroud)

它遍历层次结构,直到它到达根类,同时将每个父项的属性与其子项的属性合并(并且在默认情况下,仅使用在层次结构的最下部找到的默认值).