Introduction to PHP Reflection API

How to analyze PHP data structure with PHP

Introduction

When I started PHP coding, I wasn’t aware of the power of Reflection API and the main reason is that I didn’t need it to design my simple class, module or even my package, then I started to find it in many areas playing a major role. So in this part we will introduce Reflection API and here is the article agenda:

  1. What is Reflection API.
  2. Installation & Configuration.
  3. Usage.
  4. Conclusion.
  5. References.

1. What is Reflection API

reflection is the ability of a computer program to examine, introspect, and modify its own structure and behavior at runtime — wikipedia

The point that you can stand on and look into your code (reverse-engineering), what does it mean? let us check the following snippet of code:

/**
* Class Profile
*/
class Profile {
/**
*
@return string
*/
public function getUserName(): string
{
return 'Foo';
}
}

Now, the Profile class is a black box, using ReflectionClass, you can read what is inside it:

// instantiation
$reflectionClass = new ReflectionClass('Profile');

// get class name
var_dump
($reflectionClass->getName());
=> output: string(7) "Profile"

// get class documentation
var_dump
($reflectionClass->getDocComment());
=> output:
string(24) "/**
* Class Profile
*/
"

So ReflectionClass is like an analyst for our Profile class, and this is the main idea of the Reflection API.

PHP is giving you the key to any locked box, so we have the keys for the following:

ReflectionClass: reports information about a class.
ReflectionFunction: reports information about a function.
ReflectionParameter: retrieves information about function’s or method’s parameters.
ReflectionClassConstant: reports information about a class constant.

Check the full list on php.net.

2. Installation & Configuration:

In order to use different Reflection API’s classes, there is no installation or configuration required, it is coming as a part of the core.

3. Usage

Here, we have some examples how can we use Reflection API:

ex.1) Get the parent class for a specific class:

// here we have the child class
class Child extends Profile {
}

$class = new ReflectionClass('Child');

// here we get the list of all parents
print_r($class->getParentClass()); // ['Profile']

ex.2) Get getUserName() function documentation:

$method = new ReflectionMethod('Profile', 'getUserName');
var_dump($method->getDocComment());
=> output:
string(33) "/**
* @return string
*/"

ex.3) It can act like instanceof and is_a() to validate objects:

$class = new ReflectionClass('Profile');
$obj = new Profile();
var_dump($class->isInstance($obj)); // bool(true)
// same like
var_dump(is_a($obj, 'Profile')); // bool(true)
// same like
var_dump($obj instanceof Profile); // bool(true)

ex.4) In some situations you will find yourself stuck with unit testing and wondering, how can I test the private functions?!

No worries, here is the trick:

// add getName() scope as private
private function getName(): string
{
return 'Foo';
}
$method = new ReflectionMethod('Profile', 'getUserName');
// check if it is private so we set it as accessible
if ($method->isPrivate()) {
$method->setAccessible(true);
}
echo $method->invoke(new Profile()); // Foo

The preceding examples are quite simple, here are some areas you can find Reflection API extensively:

  1. Documentation Generator: laravel-apidoc-generator package, it is using ReflectionClass & ReflectionMethod extensively to get info about classes and methods doc blocks and then process them, checkout this block of code.
  2. Dependency Injection Container: check the full topic here.

4. Conclusion

PHP is providing a rich Reflection API that makes life easy to reach any area of the OOP structures.

PHP is giving you the tools to fix a box… and it tells you how to look inside it.

5. References

  1. http://php.net/manual/en/book.reflection.php
  2. Dependency Injection Container: https://medium.com/@MustafaMagdi/dependency-injection-di-container-in-php-a7e5d309ccc6