You might need at some point to access the pivate or protected method of a PHP class.

Of course, this is in general a bad sign because methods are not available in the public interface of the class for a reason: their implementation can be changed at any time for the given class to function correctly. They exist only to serve that class. If you want to use them from an external class, your code might get broken if the used private / protected methods are changed by the 3rd party / other developer implementing that class.

But, there are certain cases where you want to do this and is ok to do it. Maybe you just want a quick, temporary hack and you really need to quickly access that private attribute or you need to unit test that private method.

There are various discussions about unit testing private / protected methods. Some say it’s not ok, that they are not a part of the public interface of the class, they can change at any time, even be removed and that they should be tested only through the public interface of the class. So if you have a public method in the class, that calls a private method, you would need to create your test in such way that you also reach the private method through the tests for the public method; and on top of that, you also cover all the branching of that private method.
But then, are others who say that it’s ok to do it in some cases. If the private method is a complex one and it would be difficult to cover it entirely from testing the public methods that call it – than writing some tests specifically for it could work fine.

But then, how to you call a private method or how do you access a private attribute for asserting its value?

For this we can use the amazing ReflectionClass which mainly “reports information about a class”. It allows us to change the accessibility of an attribute or method of a class instance.

For example we have this class:

If we want to call “inc” from outside the class we can do it this way, using the ReflectionClass:

This will increase the $bar attribute on our instance of Foo by 5.
If we want to retrieve the value of $bar for a test, we can write:

We can apply all these for static methods and attributes too.

So this is it. I just hope that you really reached this article, you know what are you doing and you will not write some super fragile spaghetti code using this.