# PHP reflection API fundamentals

Do you ever take the time to read the code of your favourite PHP framework or library? If you have, there's a good chance that you might have seen them use [PHP's reflection API](https://secure.php.net/manual/en/book.reflection.php). And, if you don't read other people's code, [you should start doing it](https://carlalexander.ca/read-more-code/)! (It's a great learning tool.) Now, let's get back to the reflection API. This is an API that gets used quite a lot by framework and library developers. But the funny thing is that it's almost never talked about when you're looking at resources to learn PHP. (Or even advanced PHP resources for that matter.) This is unfortunate. That's because PHP's reflection API serves a unique and important purpose. That's why developers that build our frameworks and libraries use it so much.

# What's a reflection?

At this point, there's a good chance that you're telling yourself, "Well, of course, I don't know PHP's reflection API. I don't even know what you mean by reflection!" That's a reasonable reaction to have. ([My bad!](https://d3nw5tt5i784nr.cloudfront.net/uploads/2016/08/Carl.jpg)) It's the one I had the first time I came across code that used reflections. Let's start by looking at the [concept of reflection](https://en.wikipedia.org/wiki/Reflection_(computer_programming)). The first thing that you should know is that the concept of reflection isn't PHP specific. It's a concept that comes from computer science. Ok, that's fine. But what is this mysterious concept of reflection? Well, it's the idea that your code should be able to [examine](https://en.wikipedia.org/wiki/Type_introspection) and modify itself while [it's running](https://en.wikipedia.org/wiki/Run_time_(program_lifecycle_phase)). If that sounds trippy, that's because it is! We often think of our code as something static. Once you save and execute it, there's no way to make changes to it. But that's not true. And reflections is the mechanism that you use to make changes to your code as it's running. While it might sound crazy today that you would want to edit your code as its running, that wasn't always the case. Back when programmers used to program using an [assembly language](https://en.wikipedia.org/wiki/Assembly_language) this was quite common. In fact, the examine your code and modify as it ran was an inherent property of an assembly language. This property of assembly languages didn't carry over when early compiled languages appeared. But it did eventually reappear through the concept of reflection. And now a lot of programming languages support it. # What do you use them for?

So that's some of the history behind the concept of reflection. But this doesn't really help you understand what you would use it for. Or even why it's even useful. After all, you've been getting away with not using it for a while now. The most common use for reflection is for testing. When you're [testing your code](https://carlalexander.ca/introduction-wordpress-unit-testing/), you often need to examine and modify it as it's running. It's also how unit testing frameworks tend to create [mocks](https://en.wikipedia.org/wiki/Mock_object) of your classes and functions. It's also great for situations where you want to analyze code and automate some task around it. For example, documentation generation libraries can use reflections to generate documentation for your code. It's also how a lot of [dependency injection](https://carlalexander.ca/dependency-injection-wordpress/) containers inject dependencies into the objects they create. That said, as we'll see throughout the article, there are a lot of uniques uses for reflections. They don't always fit into neat categories like those we just mentioned. But what they all have in common is that they use reflections to inspect and modify code as it's running. # Overview of the PHP reflection API

Let's move on to the reflection API. If you went to check the PHP documentation earlier ([here](https://secure.php.net/manual/en/book.reflection.php)'s the link again), you might have noticed that it's massive. There are over a dozen classes, and some of them have dozens of methods. It's not realistic (or even useful for us) to go over all of them. What we'll do instead is look at the reflection API from a high level. And, from there, we'll look the reflection classes that you're the most likely to use. ## How are reflection classes structured?

While there are a lot of reflection classes, how they related to one another is pretty easy to understand. That's because, in general, every PHP construct has a corresponding reflection class. What do we mean by that? Well, let's say that you have a class that you'd like to examine. The reflection class that you'd use to do that is the [`ReflectionClass`](https://php.net/manual/en/class.reflectionclass.php) class. (Quite the obvious class name!) But if you had an object that you wanted to inspect, you'd use the [`ReflectionObject`](https://php.net/manual/en/class.reflectionobject.php) class instead. (You must be getting the idea!) ```
$classReflection = new ReflectionClass('SomeClass');

$object = new SomeClass();
$objectReflection = new ReflectionObject($object);
```

Above is how you'd create a reflection of the `SomeClass` class and a reflection of the `SomeClass` object. It's worth noting that, while we use two different classes to generate our reflections, both reflections are almost identical. In fact, the `ReflectionObject` class extends the `ReflectionClass` class. In practice, there's no reason to use one reflection class over the other. You should just use the one that fits the information you have at the time. If you just have the class name, use the `ReflectionClass` class. If you have an object, use the `ReflectionObject` class instead. Let's get back to our reflection objects. Once we've instantiated one of them, we can then use its class methods to examine the `SomeClass` class. This allows us to get answers to specific questions like: - [Is the class an interface?](https://php.net/manual/en/reflectionclass.isinterface.php) (There's no separate reflection class for interfaces or abstract classes.)
- [What's the name of the class?](https://php.net/manual/en/reflectionclass.getname.php) (This is more useful when you create a reflection of an object.) 
    - Does this class have this [constant](https://php.net/manual/en/reflectionclass.hasconstant.php), [method](https://php.net/manual/en/reflectionclass.hasmethod.php) or [property](https://php.net/manual/en/reflectionclass.hasproperty.php)?

### Diving further into reflections

But you can dig even deeper and fetch a specific [constant](https://php.net/manual/en/reflectionclass.getconstant.php), [method](https://php.net/manual/en/reflectionclass.getmethod.php) or [property](https://php.net/manual/en/reflectionclass.getproperty.php) from a class. Or you can get them all. Let's look at a small example of this in action. ```
$object = new SomeClass();
$objectReflection = new ReflectionObject($object);

$someProperty = $objectReflection->getProperty('someProperty');
```

Now, the question with this example is what did we store in the `someProperty` variable? Well, it happens that what we got from the `getProperty` method is another reflection. This reflection isn't an instance of `ReflectionClass` either. It's an instance of the [`ReflectionProperty`](https://php.net/manual/en/class.reflectionproperty.php) class. This brings us to an important fact about examining code with reflections. It's that, with reflections, you're often just dealing with other reflection classes. It's a bit like going down a rabbit hole! That said, it's is also a useful way to view the structure of these reflection classes. Let's imagine that you create a reflection using `ReflectionClass` or `ReflectionObject`. What you'll get is an instance of that class where: - Its constants are instances of the [`ReflectionClassConstant`](https://php.net/manual/en/class.reflectionclassconstant.php) class.
- Its method are instances of the [`ReflectionMethod`](https://php.net/manual/en/class.reflectionmethod.php) class.
- Its properties are instances of the [`ReflectionProperty`](https://php.net/manual/en/class.reflectionproperty.php) class.

## Getting information from reflections

Let's say that you've drilled down to the reflection object that you need. How do you get concrete information out of it? For example, how would you get the value stored in the property of an object? Well, first, you have to think about what information you want to get. In this case, we want to get the value of a property of an object. And then you have to ask yourself what is the most specific reflection that would contain this information. ```
$object = new SomeClass();
$objectReflection = new ReflectionObject($object);

$somePropertyReflection = $objectReflection->getProperty('someProperty');

$somePropertyValue = $somePropertyReflection->getValue($object);
```

The code above builds on our earlier example. We initialized a `SomeClass` object. We then created a reflection of it using the `ReflectionObject` class. Next, we want to access the `someProperty` property from our `SomeClass` object. We do that by fetching its reflection from our `ReflectionObject` object. We do that using the `getProperty` method which returns a `ReflectionProperty` object. We also stored that `ReflectionProperty` object in the `somePropertyReflection` variable. We can then use it to get the value stored in the `someProperty` property. We do that using the `getValue` method. We then stored that value in the `somePropertyValue` variable. ### Reflections are never reflections of a specific object

Now, you might have also noticed odd about our call to the `getValue` method. It's that we passed it our `object` as an argument. Why did we do that? After all, didn't we instantiate our `ReflectionObject` object using our `SomeClass` object? It's true that we did instantiate our `ReflectionObject` object using our `SomeClass` object. But the fact is that it doesn't matter that we did that. Our `ReflectionObject` object doesn't contain any information about our `SomeClass` object. This is one of the more confusing parts of using reflections. Considering how we instantiate it, you'd think that our `ReflectionObject` object would be smarter. That it'd contain information about the object that we reflected. But that's not the case. That's because, when you create a `ReflectionObject` object, you're not creating a reflection of that object. Instead, what's happening is that the `ReflectionObject` class creates a reflection of the class of the object that you gave it. (That's also why the `ReflectionObject` class extends the `ReflectionClass` class.) So, if we go back to our example, the `objectReflection` isn't a reflection of `object`. It's a reflection of the `SomeClass` class. It's unintuitive at first, but you get the hang of it eventually. ### The same goes for all the other types of reflections

What happens then when we make a call to the `getProperty` method of our `ReflectionObject` object? Well, in that case too, you're not getting a reflection of the property of an object. You're getting the reflection of a property of a class. This means that, in our example, `someProperty` isn't the reflection of the `someProperty` property of `object`. It's the reflection of the `someProperty` property of the `SomeClass` class. And that's why we have to pass `object` to the `getValue` method. Again, this isn't very intuitive when you start using reflections. That said, there are benefits to things working the way they do. For example, it means that we don't need to create multiple reflections of the `someProperty` property. If we have to examine two `SomeClass` objects, we can do this instead: ```
$object1 = new SomeClass();
$object2 = new SomeClass();

$objectReflection = new ReflectionObject($object1);

$somePropertyReflection = $objectReflection->getProperty('someProperty');

$somePropertyValue1 = $somePropertyReflection->getValue($object1);
$somePropertyValue2 = $somePropertyReflection->getValue($object2);
```

In the example above, we managed to extract two `someProperty` values using the same `ReflectionProperty` object. First, we started by creating a reflection of the `someClass` class. We created it by using the `ReflectionObject` class and passing it `object1`. (We could have also used `object2`.) Using our `objectReflection`, we get a reflection of the `someProperty` property. We then use it to extract the value of the `someProperty` property from both our objects. We then store those values in the `somePropertyValue1` and `somePropertyValue2` variables. # Reflections in practice

While we haven't seen everything that reflections can do, it's a good starting point. What we're going to do next is look at how to use reflections in a more practical context. This will allow us to go over other aspects of reflections that we haven't covered so far. ## A class to reflect

But first, we need a class that we can reflect! We don't need to make this class too complicated. It just needs methods and properties that aren't [public](https://carlalexander.ca/first-thing-learn-object-oriented-programming/). (You don't need for reflections to inspect public methods or properties!) ```
class User
{
    /**
     * The user ID.
     *
     * @var int
     */
    private $id;

    /**
     * The user's login.
     *
     * @var string
     */
    private $login;

    /**
     * The user's password.
     *
     * @var string
     */
    private $password;

    /**
     * Constructor.
     *
     * @param string $login
     * @param string $password
     */
    public function __construct($login, $password)
    {
        $this->login = $login;
        $this->password = $password;
    }
}
```

So above is a small class called `User` that we'll use for more practical examples. It has three internal private properties: `id`, `login` and `password`. For now, it doesn't have any other methods besides the constructor. The constructor itself has two parameters: `login` and `password`. Those are two of the three internal properties that our `User` class has. All that the constructor does is assigns the `login` and `password` arguments passed to it to the `login` and `password` internal variables. Now, you might wonder why we didn't put `id` as a parameter of our constructor. It's because you don't always have or need the `id` of a user when you're creating a `User` object. For example, a new user might not have its ID assigned to it right away. ## Assigning a value to a private or protected property

But what happens if you want to assign a value to the `id` of a user? Well, you could create a [setter method](https://en.wikipedia.org/wiki/Mutator_method). But this would mean that anyone can set a new ID to a user at any time. This isn't an ideal solution because the ID of a user shouldn't change if there's one. That said, this could also be part of the logic of the setter method. If a user already has an ID, don't assign it a new one like this: ```
class User
{
    // ...

    /**
     * Set the ID of a user.
     *
     * @param int $id
     */
    public function setId($id)
    {
        if (!empty($this->id)) {
            return;
        }

        $this->id = $id;
    }
}
```

### Using a reflection instead of a method

However, even if the `setId` method prevents someone from overwriting the `id` property, it doesn't mean that the method should exist. Instead of creating the `setId` method, you could use reflections to add the `id` to a `User` object whenever you need it. Let's look at how we can do that. ```
class UserRepository
{
    /**
     * The user's login.
     *
     * @var mysqli
     */
    private $mysql;

    // ...

    public function persist(User $user) 
    {
        $result = $this->mysql->query('INSERT INTO ...');

        if (!$result) {
            throw new \Exception($this->mysql->error);
        }

        $userReflection = new ReflectionObject($user);
        $idPropertyReflection = $userReflection->getProperty('id');

        $idPropertyReflection->setAccessible(true);
        $idPropertyReflection->setValue($user, $this->mysql->insert_id);
        $idPropertyReflection->setAccessible(false);

        return $user;
    }
}
```

Above we have part of the `UserRepository` class. If you're not familiar with the [concept of repository](https://martinfowler.com/eaaCatalog/repository.html), it's class that acts as a collection of objects. If you need a [persistence](https://en.wikipedia.org/wiki/Persistence_(computer_science)) layer, it can also handle persisting objects inside a database. (If that's what you use for persistence.) This is what the `persist` method does. It takes a `User` object as an argument and persists it in the MySQL database. Only once we've persisted our `User` object do we assign it an `id`. So instead of using a `setId` method to assign the `id`, we're using reflections. But first, we need to save our `User` object inside the database. To do that, our `UserRepository` class uses the [`mysqli`](https://secure.php.net/manual/en/class.mysqli.php) class. This is a PHP class used to represent a connection with a MySQL database. Our `UserRepository` already has an instantiated `mysqli` object stored in the `mysql` property. So we can assume that our connection to the MySQL database works already. All that we have to do then is create a query to insert our new user into the database. We do that using the `query` method to run an [`INSERT`](https://dev.mysql.com/doc/refman/8.0/en/insert.html) query. We're not showing the query because it's not relevant here. That said, [never forget to sanitize your database inputs](https://xkcd.com/327/) if you run queries like this! We store the result of the query in the `result` variable. We then check to see if it's `false`. If it is, we throw an exception with the error message stored in the [`error`](https://secure.php.net/manual/en/mysqli.error.php) property of the `mysqli` object. Once we're passed this [guard clause](https://carlalexander.ca/mastering-php-conditionals/), we can start using our reflections. First, we create a reflection of the `User` object using the `ReflectionObject` class. Then we create a reflection of the `id` property using the `getProperty` method of our `User` reflection. ### Changing the accessibility of a property

This shouldn't feel too new to you as it's what we saw earlier about diving into reflections. What's new is the last half of this section. It's where we change the value of an internal variable of an object. By default, reflections don't override the scope of a variable. This means that, while we have a reflection of the `id` property, we can't do much with it. It's still a `private` property. To change that, we need to use the [`setAccessible`](https://secure.php.net/manual/en/reflectionproperty.setaccessible.php) method. This changes the scope of a property to `public`. Once we've done that, the `ReflectionProperty` object will let us modify the value of the `id` property. At that point, all that we have to do is call the [`setValue`](https://secure.php.net/manual/en/reflectionproperty.setvalue.php) method. We pass it our `User` object and the ID of the user we inserted in the database. The `mysqli` object always stores that ID in the [`insert_id`](https://secure.php.net/manual/en/mysqli.insert-id.php) property. Once we've set the value of the `id` property, we need to revert the accessibility change that we did at first. Otherwise, the `id` property will stay accessible as long as the object exists. (And we don't want that!) That's why we make a call to the `setAccessible` method once more after the call to the `setValue` method. ## Calling a private or protected method

We can also do what we just did for private or protected properties with object methods. We can take a private or protected method and make it public so that we can use it. This is also something that can be useful in certain scenarios. ```
class User
{
    // ...

    /**
     * Constructor.
     *
     * @param string $login
     * @param string $password
     */
    public function __construct($login, $password)
    {
        $this->login = $login;
        $this->password = $this->maybeEncode($password);
    }

    /**
     * Encodes the password using the BCRYPT algorithm if it's not already
     * encoded.
     *
     * @param string $password
     *
     * @return string
     */
    private function maybeEncode($password)
    {
        if (!password_needs_rehash($password, PASSWORD_BCRYPT)) {
            return $password;
        }

        return password_hash($password, PASSWORD_BCRYPT);
    }
}
```

Above is an updated version of our `User` class. We added a new private method called `maybeEncode`. The purpose of this method is to encode our password if it wasn't encoded already. We do that by using two built-in PHP functions: [`password_needs_rehash`](https://secure.php.net/manual/en/function.password-needs-rehash.php) and [`password_hash`](https://secure.php.net/manual/en/function.password-hash.php). The `maybeEncode` method starts with a guard clause. We use the `password_needs_rehash` function to check if we need to encode the given `password`. If we don't need to, we return it. Otherwise, we `password_hash` function to encode the given `password`. It's also worth noting that both functions have a second argument where we pass the `PASSWORD_BCRYPT` constant. This is the [password algorithm constant](https://secure.php.net/manual/en/password.constants.php) that we'll use to encode the given `password`. You can also use the `PASSWORD_DEFAULT` constant if you prefer to not specify an algorithm. That said, `PASSWORD_BCRYPT` is the current `PASSWORD_DEFAULT` value. ### Using a method reflection

Now that we have a private method in our `User` class, we can look at how to create a reflection for it. This is pretty straightforward and follows the similar pattern that we've seen so far. You can view the code below: ```
$userReflection = new ReflectionObject($user);

$maybeEncodeReflection = $userReflection->getMethod('maybeEncode');

$maybeEncodeReflection->setAccessible(true);
$maybeEncodeReflection->invoke($user, $password);
$maybeEncodeReflection->setAccessible(false);
```

Unlike our previous example with the `UserRepository` class, this is just a code sample. That said, you'll notice that we once again start by reflecting our `User` object using the `ReflectionObject` class. You could have used the `ReflectionClass` class instead if you wanted as well. After that is where things diverge a bit. First, we do a call to the `getMethod` method. We use it to ask for a reflection of the `maybeEncode` method. Next, we want to make the method accessible. We use the [`setAccessible`](https://php.net/manual/en/reflectionmethod.setaccessible.php) method like we did with our private property. This will allow us to use our `maybeEncode` method. To make a call to a method reflection, you have to use the [`invoke`](https://php.net/manual/en/reflectionmethod.invoke.php) method. The `invoke` works the same way as the other reflection methods that we've seen so far. You have to first pass it the object that you want the reflection to interact with. ### Generating a closure

There's also another way to access a private method using reflections. It's by generating a [closure](https://en.wikipedia.org/wiki/Closure_(computer_programming)) for the method that we want to reflect. Here's an example to show you how to do it: ```
$userReflection = new ReflectionObject($user);

$maybeEncodeReflection = $userReflection->getMethod('maybeEncode');

$maybeEncodeClosure = $maybeEncodeReflection->getClosure($user);

$maybeEncodeClosure($password);
```

As you might have noticed, this is a modified version of our previous example. The first part of the example is the same. We created a reflection of our `User` object. We then used that reflection to create a reflection of the `maybeEncode` method. The last section of the example is where things changed. First, we don't use `setAccessible` method. We don't need to change the accessibility of the `maybeEncode` method to use it in this scenario. Instead, we only need to call the `getClosure` method. This generates a [`Closure`](https://secure.php.net/manual/en/class.closure.php) object. This object calls the `maybeEncode` method in the `User` object that we passed it. We do that on the last line. We use the `maybeEncodeClosure` variable as a function. We pass it our `password` as an argument. # A good foundation

This is only a fraction of all that you can do using reflections. As we said at the beginning, this covers the most common uses of reflections. There are a lot more classes and methods, but their use is a lot more situational. With what you've seen here, you're in good shape to use reflections to solve interesting problems. That said, most of its use will be around testing. Reflections and testing often go hand in hand. So, if you're interested in testing, this is all good knowledge to have! But regardless that you do testing or not (you should though!), reflections are important computer science concept. You might encounter them in another programming language later in your career. *Photo Credit: [Erik Eastman](https://unsplash.com/photos/7jSRJZJSvy4)*