parser-reflection
parser-reflection copied to clipboard
ReflectionClass::getParentClass with preloaded classes
I discovered a strange behaviour regardings classes which are already loaded / declared.
<?php
// A.php
class A
{
protected $test = 'Hello World';
}
<?php
// B.php
class B extends A
{
}
<?php
// index.php
require_once('vendor/autoload.php');
$locator = new \Go\ParserReflection\Locator\CallableLocator(function($className) {
if (strpos($className, '\\') !== 0) {
$className = '\\' . $className;
}
if ($className === '\A') {
return __DIR__ . '/A.php';
}
if ($className === '\B') {
return __DIR__ . '/B.php';
}
return false;
});
\Go\ParserReflection\ReflectionEngine::init($locator);
//require_once('A.php');
$parsedFile = new \Go\ParserReflection\ReflectionFile('B.php');
$fileNameSpaces = $parsedFile->getFileNamespaces();
foreach ($fileNameSpaces as $namespace) {
$classes = $namespace->getClasses();
foreach ($classes as $class) {
foreach ($class->getProperties() as $property) {
echo "Found class property: ", $class->getName(), '->', $property->getName(), ' default Value: ', $property->getValue(), PHP_EOL;
}
}
}
When you run this code the output is:
Found class property: B->test default Value: Hello World
But if I remove the comment before "require_once('A.php');" to load class A the output is:
Fatal error: Uncaught ReflectionException: Cannot access non-public member A::test
This problem only occurs when calling "getParentClass" (getProperties calls internally getParentClass). "getParentClass" returns a \ReflectionClass instead of a "\Go\ParserReflection\ReflectionClass".
The problem seems to be here: https://github.com/goaop/parser-reflection/blob/master/src/Traits/ReflectionClassLikeTrait.php#L445
It could be fixed with:
if (class_exists($extendsName, false)) {
$parentClass = new parent($extendsName);
if ($parentClass->isUserDefined()) {
$parentClass = new static($extendsName);
}
} else {
$parentClass = new static($extendsName);
}
What do you think about this?
This problem only occurs when calling "getParentClass" (getProperties calls internally getParentClass). "getParentClass" returns a \ReflectionClass instead of a "\Go\ParserReflection\ReflectionClass".
This is system-wide behavior, since it also manifests itself in getMethods method as I've reported before in #16.