ReflectionClass :: getProperties () также получает свойства родительского объекта? - PullRequest
5 голосов
/ 28 марта 2012

Я пытаюсь получить доступ / изменить свойства класса 'Parent через Reflection.

Если я запускаю ReflectionClass :: getProperties () на дочернем объекте, он также возвращает любые свойства, которые родительский объект имеет какхорошо?

Если это не так, есть ли способ получить доступ к родительским свойствам с помощью Reflection?

Ответы [ 3 ]

12 голосов
/ 28 марта 2012

Я разработал этот быстрый тест. Похоже, что частные свойства родительского объекта скрыты, когда вы получаете свойства дочерних классов. Однако, если вы вызовете 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"
  }
}
6 голосов
/ 17 июня 2015

Хотя краткий, принятый ответ пренебрегает возможностью детского класса со многими предками. Это метод экземпляра, который я использую для достижения этой цели:

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;
}

Он перемещается вверх по иерархии, пока не достигнет корневого класса, при этом объединяя свойства каждого родителя со свойствами его дочерних элементов (и в случае значений по умолчанию используются только значения по умолчанию, найденные в самой нижней части иерархии).

0 голосов
/ 28 марта 2012

Я думаю, вы не получите родительские частные свойства, потому что дочерний класс не может получить к ним доступ

...