I am trying to access/change the properties of a class' Parent through Reflection.
If I run ReflectionClass::getProperties() on the child, does it also return any properties that the Parent has as well?
If it doesn't, is there any way to access the parent properties using Reflection?
I worked up this quick test. It looks like private properties of the parent are hidden when you get the child classes's properties. However, if you invoke getParentClass()
then getProperties()
you will have the missing set of private props.
<?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
Output (notice the private prop Ford::model
is missing):
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 (contains all the properties of the Ford class):
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"
}
}
Though succinct, the accepted answer neglects the possibility of a child class with many ancestors. This is the instance method I use to achieve this:
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;
}
It traverses up the hierarchy until it reaches the root class, while merging the properties of each parent with the properties of its children (and in the case of defaults, uses only the defaults found in the lowermost part of the hierarchy).
I think you won't get the parent private properties because the child class can't access them