Private parts exposed in public
Tags: php, reflection
Published: 2018-08-08 17:36:19

---
title: Private parts exposed in public
published: true
description: How to gain access to protected and private properties in PHP
tags: php, reflection
cover_image: https://4.bp.blogspot.com/-Yg8AQVSXAxw/VcJOc9ZAqYI/AAAAAAAANk8/wVKVeHeA3co/s1600/spot%2Bsiamo%2Btutti%2Bmaniaci%2Bdella%2Bsimmenthal%2Bcon%2Bchristian%2Bde%2Bsica%2B2.jpg
---

It's said that a good object keeps private or protected his properties, so nobody can harm the business logic. It's a wise advice, indeed, but sometimes we *want* to break things: maybe we need to gain access of a private connection managed by an external library, maybe we just want to see the world burn. An example of the first case happened to me a lot of years ago, when I was working on a strange Wordpress integration: I needed the underlying `mysqli` connection, but it was stored in a `dbh` property of the `$wpdb` singleton of class `\wpdb`. I couldn't edit the class to make `dbh` property public, but I needed the connection. What to do? We all know that a private or protected properties cannot be accessed from outside the instance through `->` operator! A `$object->privateProp` will *always* fail!

That's not entirely true. Quite, but not entirely. There's a little detail that I think it's not so known: the access control to methods and properties is done checking the context from which we are working. So, if we are *inside* a method of the class, we can access private or protected properties of *any* instance of that class.

Enough talk, let's do some code. Imagine that we have a third-party library, that we cannot modify, that do this kind of things:

```php
// begin read only code

class DeepThought {
    protected $theAnswer = 42;
    private $theQuestion = 'How many roads...';
}

$singleton = new DeepThought();

// end read only code
```

We disperately want to know `theAnswer`: we know that is protected, so we can work on it. We know that a protected property can be accessed from extended classes, so we write this piece of code:

```php
class Towel extends DeepThought {
    public static function getTheAnswer(DeepThought $instance): int
    {
        return $instance->theAnswer;
    }
}

echo Towel::getTheAnswer($singleton);
```

Do you see the magic? `Towel` extends `DeepThought`, so can legitimately access his protected properties. When we call `Towel::getTheAnswer()` we are in the `Towel` context, so `$instance->theAnswer` is also legit.

But `theAnswer` is merely protected, and we also want to know `theQuestion`, that's private. Extending the class we still have not access to private properties... we need a bigger towel! :-)

Reflection comes to the rescue:

```php
$refl = new ReflectionProperty(DeepThought::class, 'theQuestion');
$refl->setAccessible(true);

echo $refl->getValue($singleton);
```

Note that Reflection works also on protected properties, but I've presented it last for the sake of narration. We just instantiate a ReflectionProperty for `theQuestion`: that's like a tool that can inspect or edit some attributes without changing the code. After we use the reflection to make the property accessible, and lastly we apply our edited property description to the original object. It's like `.call()` in JavaScript.

That's all! With these two techniques you can tear apart any class to extract the gems inside. But stay wise! Objects with private properties often have good reasons to be designed that way. No developer take care of backward compatibility for private properties: as in real life, if you play with other's private parts without consent you can get in trouble!