Php get private properties of object

In PHP, the visibility of a property, a method, or a constant can be defined by prefixing the declaration using keywords public, protected or private. Here is how these modifiers work.

  • public - Class members declared public can be accessed everywhere.
  • protected - Class members declared protected can be accessed only within the class itself and by inheriting and parent classes.
  • private - Class members declared as private may only be accessed by the class that defines the member.

Generally, the class members are declared private for certain reasons. One is to implement encapsulation which makes the class members available inside of the originating class only i.e. to hide data from the user of the class and can only be modified using public getter and setter methods.

But in certain scenarios, you might want to access these private members outside of the class. There’s a workaround in PHP using which you can do so. First, let’s check how to access private methods.

Accessing private methods

First, check the following class.

class Foo 
{
    private function privateMethod() {
        return 'Hogwarts';
    }
}

As you can see, the privateMethod is a private method and if we want to access it outside of the class like so, we would get a fatal error.

$foo = new Foo;
$foo->privateMethod(); 
// Fatal error:  Uncaught Error: Call to private method 
// Foo::privateMethod() from context

To get around this, we can use PHP’s in-built ReflectionMethod class which can give handlful of information about the class. And also can “reverse engineer” things for us.

Basically, it shows the “mirror” to the class so that it can learn about itself. And here’s how you can use it.

$reflectionMethod = new ReflectionMethod('Foo', 'privateMethod');
$reflectionMethod->setAccessible(true);

echo $reflectionMethod->invoke(new Foo); // Hogwarts

As you can see, the ReflectionMethod constructor accepts two parameters: “Class name” and “Method name”. In our case, we passed in Foo as the class name and privateMethod method name as we want to access this method.

Next, we’ll need to make the private method accessible outside of the class. For this, we have used the setAccessible method on the object and set it to true. This will allow protected and private methods to be invoked on-the-fly.

And lastly, we can invoke the method using the invoke method on the object and passing in the object of the class (new Foo) as its only parameter for which we’re accessing the method.

And that is how you can access a private method of the class.

Accessing private properties

Similarly, you can also access the private properties of the class but the only distinction here is instead of using ReflectionMethod, we’d need to used ReflectionProperty class like so.

class Foo 
{
    private $privateProperty = 'Harry Potter!';    
}

$property = new ReflectionProperty('Foo', 'privateProperty');
$property->setAccessible(true);

echo $property->getValue(new Foo); // Harry Potter!

As you can see, in this case, we’ve used getValue to fetch the value of the property.

Beep! Beep! I'm also running a YouTube channel which I hope you're going to love!

Last week, Caleb tweeted about a nifty function called invade - that he had made to easily work with private properties and methods.

😈 Whatcha think of my new favorite helper method?

That property/method protected or private? No problemoooo 🔓 pic.twitter.com/HqMXKKpRsJ

— Caleb Porzio (@calebporzio) February 11, 2022

He added that invade function to Livewire. Because I could see myself using this in non-Laravel projects, I packaged up the function in a new package called spatie/invade.

Using the package

Imagine you have this class defined which has a private property and method.

class MyClass 
{
    private string $privateProperty = 'private value';

    private function privateMethod(): string
    {
        return 'private return value';
    }
}

$myClass = new Myclass();

This is how you can get the value of the private property using the invade function.

invade($myClass)->privateProperty; // returns 'private value'

The invade function also allows you to change private values.

invade($myClass)->privateProperty = 'changed value';
invade($myClass)->privateProperty; // returns 'changed value

Using invade, you can also call private functions.

invade($myClass)->privateMethod(); // returns 'private return value'

How the package works under the hood

Accessing private properties and methods seems magical, but it's pretty easy to achieve using reflection. On its reflection classes, PHP has a method setAccessible that can make private things public in runtime.

The invade function will pass the given object to an Invader class. That invader class has magic __get, __set and __call methods that will execute on each interaction with the given object. Before forwarding the call to the object, it will be made accessible.

The source code is so small that I can share it in full in this post.

namespace Spatie\Invade;

use ReflectionClass;

class Invader
{
    public object $obj;
    public ReflectionClass $reflected;

    public function __construct(object $obj)
    {
        $this->obj = $obj;
        $this->reflected = new ReflectionClass($obj);
    }

    public function __get(string $name): mixed
    {
        $property = $this->reflected->getProperty($name);

        $property->setAccessible(true);

        return $property->getValue($this->obj);
    }

    public function __set(string $name, mixed $value): void
    {
        $property = $this->reflected->getProperty($name);

        $property->setAccessible(true);

        $property->setValue($this->obj, $value);
    }

    public function __call(string $name, array $params = []): mixed
    {
        $method = $this->reflected->getMethod($name);

        $method->setAccessible(true);

        return $method->invoke($this->obj, ...$params);
    }
}

And that's all there is to it!

Should you use this?

I don't think you should use this in the code of regular projects. In that context, you'll have to design your code in such a way that everything that should be called is easily callable.

Three situations come to mind where I can see invade being used:

  1. Inside packages that add specific, magical behaviour, like Livewire
  2. Inside a package to test some of its own behaviour that is not publicly accessible. The first example that comes to mind is non-public methods inside a package service provider (although it could be argued to make such a method public as well).
  3. Inside the test suite of package or project where you need to hook into private state/behaviour of other packages. In this case, it might also be a good idea to create an issue on that other package, asking the maintainer to make the state/behaviour accessible in a regular way.

Even though you might argue that it's not a good idea to do so, it's very cool that PHP allows functions like invade to be created.

How can I access private properties in PHP?

Way to Access Private Property or Method In PHP.
class Foo { private function privateMethod() { return 'howdy'; } } $foo = new Foo; $foo->privateMethod(); ... .
$reflectionMethod = new ReflectionMethod('Foo', 'privateMethod'); $reflectionMethod->setAccessible(true); echo $reflectionMethod->invoke(new Foo);.

How do you access the private property and methods outside the class using class object in PHP?

As you can see, the privateMethod is a private method and if we want to access it outside of the class like so, we would get a fatal error. To get around this, we can use PHP's in-built ReflectionMethod class which can give handlful of information about the class. And also can “reverse engineer” things for us.

What is PHP visibility?

PHP has three visibility keywords - public, private and protected. A class member declared with public keyword is accessible from anywhare. A protected member is accessible from within its class and by inheriting class.

What is the use of reflection in PHP?

The term “reflection” in software development means that a program knows its own structure at runtime and can also modify it. This capability is also referred to as “introspection”. In the PHP area, reflection is used to ensure type safety in the program code.