PHP Reflection
Nette\Utils\Reflection is a static class with useful functions for PHP reflection. Its purpose is to fix flaws in native classes and to unify behavior across different versions of PHP.
Installation:
composer require nette/utils
All examples assume the following class alias is defined:
use Nette\Utils\Reflection;
areCommentsAvailable(): bool
Finds out if reflection has access to PHPdoc comments. Comments may not be available due to the opcode cache, see for example the directive opcache.save-comments.
expandClassName(string $name, ReflectionClass $context): string
Expands the $name
of the class to full name in the context of the $context
, ie in the context of its
namespace and defined aliases. Thus, it returns how the PHP parser would understand $name
if it were written in the
body of the $context
.
namespace Foo;
use Bar;
class DemoClass
{
// new Bar, new Baz
}
$context = new ReflectionClass(Foo\DemoClass::class);
Reflection::expandClassName('Bar', $context); // 'Bar'
Reflection::expandClassName('Baz', $context); // 'Foo\Baz'
getMethodDeclaringMethod(ReflectionMethod $method): ReflectionMethod
Returns a reflection of a method that contains a declaration of $method
. Usually, each method is its own
declaration, but the body of the method can also be in the trait and under a different name.
Because PHP does not provide enough information to determine the actual declaration, Nette uses its own heuristics, which should be reliable.
trait DemoTrait
{
function foo()
{
}
}
class DemoClass
{
use DemoTrait {
DemoTrait::foo as foo2;
}
}
$method = new ReflectionMethod('DemoClass::foo2');
Reflection::getMethodDeclaringMethod($method); // ReflectionMethod('DemoTrait::foo')
getParameterDefaultValue(ReflectionParameter $param)
Returns the default value of $param
in a function or method. If it is a constant, it returns its value. If the
parameter does not have a default value or the constant cannot be resolved, it throws ReflectionException
.
class DemoClass
{
function foo($param = PDO::FETCH_BOTH)
{
}
}
$method = new ReflectionMethod('DemoClass::foo');
Reflection::getParameterDefaultValue($method->getParameters()[0]);
getParameterType(ReflectionParameter $param): ?string
Returns the type of the function or method $param
parameter and resolves self
and parent
to the actual class name. If the parameter has no type, it returns null
, if it has a union or intersection type it
throws Nette\InvalidStateException
.
class DemoClass
{
function foo(self $param)
{
}
}
$method = new ReflectionMethod('DemoClass::foo');
Reflection::getParameterType($method->getParameters()[0]); // 'DemoClass'
This method was created when PHP did not have union and intersection types. It is replaced by the method Nette\Utils\Type::fromReflection().
getPropertyDeclaringClass(ReflectionProperty $prop): ReflectionClass
Returns a reflection of a class or trait that contains a declaration of property $prop
. Property can also be
declared in the trait.
Because PHP does not provide enough information to determine the actual declaration, Nette uses its own heuristics, which are not reliable.
trait DemoTrait
{
public $foo;
}
class DemoClass
{
use DemoTrait;
}
$prop = new ReflectionProperty(DemoClass::class, 'foo');
Reflection::getPropertyDeclaringClass($prop); // ReflectionClass('DemoTrait')
getPropertyType(ReflectionProperty $prop): ?string
Returns the type of property $prop
and resolves self
and parent
to the actual class
name. If property has no type, it returns null
, if it has a union or intersection type it throws
Nette\InvalidStateException
.
class DemoClass
{
public self $foo;
}
$prop = new ReflectionProperty(DemoClass::class, 'foo');
Reflection::getPropertyType($prop); // 'DemoClass'
This method was created when PHP did not have union and intersection types. It is replaced by the method Nette\Utils\Type::fromReflection().
getReturnType(ReflectionFunctionAbstract $func): ?string
Returns the return type of the function or method $func
and resolves self
, static
and
parent
to the actual class name. If the function does not have a return type, it returns null
, if it has
a union or intersection type it throws Nette\InvalidStateException
.
class DemoClass
{
function foo(): self
{
}
}
$method = new ReflectionMethod('DemoClass::foo');
Reflection::getReturnType($method); // 'DemoClass'
This method was created when PHP did not have union and intersection types. It is replaced by the method Nette\Utils\Type::fromReflection().
isBuiltinType(string $type): bool
Determines if $type
is PHP built-in type. Otherwise, it is the class name.
Reflection::isBuiltinType('string'); // true
Reflection::isBuiltinType('Foo'); // false
toString($reflection): string
Converts a reflection to a human readable string.
$func = new ReflectionFunction('func');
echo Reflection::toString($func); // 'func' ('func()' since v3.2.0)
$class = new ReflectionClass('DemoClass');
echo Reflection::toString($class); // 'DemoClass'
$method = new ReflectionMethod('DemoClass', 'foo');
echo Reflection::toString($method); // 'DemoClass::foo' ('DemoClass::foo()' since v3.2.0)
$param = new ReflectionParameter(['DemoClass', 'foo'], 'param');
echo Reflection::toString($param); // '$param in DemoClass::foo()'
$prop = new ReflectionProperty('DemoClass', 'foo');
echo Reflection::toString($prop); // 'DemoClass::$foo'