Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 97169c7

Browse files
committed
Added automatic resolving of the class that defined a property or method
1 parent 42547c4 commit 97169c7

File tree

3 files changed

+65
-4
lines changed

3 files changed

+65
-4
lines changed

tests/example_classes.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
class example_class {
66

7-
private $example_string_property;
8-
private $example_array_property;
7+
protected $example_string_property;
8+
protected $example_array_property;
99

1010
public function __construct() {
1111
$this->example_string_property = uniqid();
@@ -25,3 +25,15 @@ public function get_value($property_name) {
2525
}
2626

2727
}
28+
29+
class example_child_class extends example_class {
30+
31+
protected $example_child_string_property;
32+
33+
public function __construct() {
34+
$this->example_child_string_property = uniqid();
35+
36+
parent::__construct();
37+
}
38+
39+
}

tests/utils/ReflectionTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@
1414
class ReflectionTest extends TestCase {
1515

1616
private $example_object;
17+
private $example_child_object;
1718

1819
public function setUp() {
1920
$this->example_object = new example_class();
21+
$this->example_child_object = new example_child_class();
2022
}
2123

2224
public function tearDown() {
2325
unset($this->example_object);
26+
unset($this->example_child_object);
2427
}
2528

2629
/**
@@ -41,6 +44,26 @@ public function dataGetProperty(): array {
4144
];
4245
}
4346

47+
/**
48+
* @dataProvider dataGetPropertyFromChild
49+
*/
50+
public function testGetPropertyFromChild(string $property_name, string $expected_type) {
51+
$reflected_value = reflection::get_property($this->example_child_object, $property_name);
52+
$actual_value = $this->example_child_object->get_value($property_name);
53+
54+
$this->assertInternalType($expected_type, $reflected_value);
55+
$this->assertSame($actual_value, $reflected_value);
56+
}
57+
58+
public function dataGetPropertyFromChild(): array {
59+
return array_merge(
60+
$this->dataGetProperty(),
61+
[
62+
['example_child_string_property', 'string'],
63+
]
64+
);
65+
}
66+
4467
public function testSetProperty() {
4568
$expected_value = 'wow such value';
4669
$property_name = 'example_string_property';

utils/reflection.php

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,30 @@
66

77
class reflection {
88

9+
/**
10+
* Search for the class name that a property is defined in. This is useful
11+
* as the reflection API uses that and not the class of the actual object.
12+
*
13+
* @param string $class_name The name of the starting class
14+
* @param string $name The name of the thing to search for
15+
* @param boolean $method If the thing being serched for is a method
16+
*
17+
* @return string The name of the owner class
18+
*/
19+
private static function resolve_class(string $class_name, string $name, bool $method): string {
20+
$exists = ($method) ? 'method_exists' : 'property_exists';
21+
22+
do {
23+
if ($exists($class_name, $name)) {
24+
return $class_name;
25+
}
26+
27+
$class_name = get_parent_class($class_name);
28+
} while ($class_name !== false);
29+
30+
throw new \Exception("Unable to find class for the property {$property_name}");
31+
}
32+
933
/**
1034
* Gets the value of an object property
1135
*
@@ -15,7 +39,8 @@ class reflection {
1539
* @return mixed The value
1640
*/
1741
public static function get_property($object, string $property_name) {
18-
$property = new \ReflectionProperty(get_class($object), $property_name);
42+
$class_name = static::resolve_class(get_class($object), $property_name, false);
43+
$property = new \ReflectionProperty($class_name, $property_name);
1944
$property->setAccessible(true);
2045

2146
return $property->getValue($object);
@@ -31,7 +56,8 @@ public static function get_property($object, string $property_name) {
3156
* @return void
3257
*/
3358
public static function set_property($object, string $property_name, $value) {
34-
$property = new \ReflectionProperty(get_class($object), $property_name);
59+
$class_name = static::resolve_class(get_class($object), $property_name, false);
60+
$property = new \ReflectionProperty($class_name, $property_name);
3561
$property->setAccessible(true);
3662

3763
$property->setValue($object, $value);

0 commit comments

Comments
 (0)