Can I get the value of a private property with Reflection?

20,330

Solution 1

class A
{
    private $b = 'c';
}

$obj = new A();

$r = new ReflectionObject($obj);
$p = $r->getProperty('b');
$p->setAccessible(true); // <--- you set the property to public before you read the value

var_dump($p->getValue($obj));

Solution 2

Please, note that accepted answer will not work if you need to get the value of a private property which comes from a parent class.

For this you can rely on getParentClass method of Reflection API.

Also, this is already solved in this micro-library.

More details in this blog post.

Solution 3

getProperty throws an exception, not an error. The significance is, you can handle it, and save yourself an if:

$ref = new ReflectionObject($obj);
$propName = "myProperty";
try {
  $prop = $ref->getProperty($propName);
} catch (ReflectionException $ex) {
  echo "property $propName does not exist";
  //or echo the exception message: echo $ex->getMessage();
}

To get all private properties, use $ref->getProperties(ReflectionProperty::IS_PRIVATE);

Solution 4

In case you need it without reflection:

public function propertyReader(): Closure
{
    return function &($object, $property) {
        $value = &Closure::bind(function &() use ($property) {
            return $this->$property;
        }, $object, $object)->__invoke();
         return $value;
    };
}

and then just use it (in the same class) like this:

$object = new SomeObject();
$reader = $this->propertyReader();
$result = &$reader($object, 'some_property');
Share:
20,330
Alex
Author by

Alex

I'm still learning so I'm only here to ask questions :P

Updated on February 15, 2021

Comments

  • Alex
    Alex about 3 years

    It doesn't seem to work:

    $ref = new ReflectionObject($obj);
    
    if($ref->hasProperty('privateProperty')){
      print_r($ref->getProperty('privateProperty'));
    }
    

    It gets into the IF loop, and then throws an error:

    Property privateProperty does not exist

    :|

    $ref = new ReflectionProperty($obj, 'privateProperty') doesn't work either...

    The documentation page lists a few constants, including IS_PRIVATE. How can I ever use that if I can't access a private property lol?