Reflection > getPropertyValue() method > look for the property in parent classes

This commit is contained in:
Meritoo
2019-04-13 18:28:53 +02:00
parent 6f90f5a249
commit eb8fa110ad
3 changed files with 68 additions and 39 deletions

View File

@@ -7,6 +7,7 @@ Common and useful classes, methods, exceptions etc.
1. Travis CI > run many tasks using Phing > update configuration 1. Travis CI > run many tasks using Phing > update configuration
2. Template with placeholders > verification of placeholders without values > make stronger and point out which are 2. Template with placeholders > verification of placeholders without values > make stronger and point out which are
missing missing
3. Reflection > getPropertyValue() method > look for the property in parent classes
# 1.0.2 # 1.0.2

View File

@@ -217,54 +217,76 @@ class Reflection
} catch (\ReflectionException $exception) { } catch (\ReflectionException $exception) {
/* /*
* 2nd try: * 2nd try:
* Look for the get / has / is methods * Look for the property in parent classes
*/ */
$class = new \ReflectionObject($object); if (null === $reflectionProperty) {
$valueFound = false; $propertyFound = false;
$reflectionProperties = self::getProperties($object, null, true);
if ($force || $class->hasProperty($property)) {
$property = Inflector::classify($property);
$getterPrefixes = [
'get',
'has',
'is',
];
foreach ($getterPrefixes as $prefix) {
$getterName = sprintf('%s%s', $prefix, $property);
if ($class->hasMethod($getterName)) {
$method = new \ReflectionMethod($object, $getterName);
/*
* Getter is not accessible publicly?
* I have to skip it, to avoid an error like this:
*
* Call to protected method My\ExtraClass::getExtraProperty() from context 'My\ExtraClass'
*/
if ($method->isProtected() || $method->isPrivate()) {
continue;
}
$value = $object->{$getterName}();
$valueFound = true;
foreach ($reflectionProperties as $reflectionProperty) {
if ($reflectionProperty->getName() === $property) {
$propertyFound = true;
break; break;
} }
} }
}
if (!$valueFound && null !== $reflectionProperty) { if ($propertyFound && null !== $reflectionProperty) {
$reflectionProperty->setAccessible(true);
$value = $reflectionProperty->getValue($object);
$reflectionProperty->setAccessible(false);
}
} else {
/* /*
* Oops, value of the property is still unknown
*
* 3rd try: * 3rd try:
* Let's modify accessibility of the property and try again to get value * Look for the get / has / is methods
*/ */
$reflectionProperty->setAccessible(true); $class = new \ReflectionObject($object);
$value = $reflectionProperty->getValue($object); $valueFound = false;
$reflectionProperty->setAccessible(false);
if ($force || $class->hasProperty($property)) {
$property = Inflector::classify($property);
$getterPrefixes = [
'get',
'has',
'is',
];
foreach ($getterPrefixes as $prefix) {
$getterName = sprintf('%s%s', $prefix, $property);
if ($class->hasMethod($getterName)) {
$method = new \ReflectionMethod($object, $getterName);
/*
* Getter is not accessible publicly?
* I have to skip it, to avoid an error like this:
*
* Call to protected method My\ExtraClass::getExtraProperty() from context 'My\ExtraClass'
*/
if ($method->isProtected() || $method->isPrivate()) {
continue;
}
$value = $object->{$getterName}();
$valueFound = true;
break;
}
}
}
if (!$valueFound) {
/*
* Oops, value of the property is still unknown
*
* 4th try:
* Let's modify accessibility of the property and try again to get value
*/
$reflectionProperty->setAccessible(true);
$value = $reflectionProperty->getValue($object);
$reflectionProperty->setAccessible(false);
}
} }
} }
} }

View File

@@ -309,6 +309,12 @@ class ReflectionTest extends BaseTestCase
self::assertEquals($username, Reflection::getPropertyValue($f, 'username')); self::assertEquals($username, Reflection::getPropertyValue($f, 'username'));
} }
public function testGetPropertyValueFromParentClass(): void
{
$c = new C();
self::assertEquals(1, Reflection::getPropertyValue($c, 'count', true));
}
public function testGetPropertyValuesFromEmptySource() public function testGetPropertyValuesFromEmptySource()
{ {
self::assertEquals([], Reflection::getPropertyValues([], 'something')); self::assertEquals([], Reflection::getPropertyValues([], 'something'));