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

Viewed 23296

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?

5 Answers

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');

Without reflection, one can also do

class SomeHelperClass {
    // Version 1
    public static function getProperty1 (object $object, string $property) {
        return Closure::bind(
            function () use ($property) {
                return $this->$property;
            },
            $object,
            $object
        )();
    }

    // Version 2
    public static function getProperty2 (object $object, string $property) {
        return (
            function () use ($property) {
                return $this->$property;
            }
        )->bindTo(
            $object,
            $object
        )->__invoke();
    }
}

and then something like

SomeHelperClass::getProperty1($object, $propertyName)
SomeHelperClass::getProperty2($object, $propertyName)

should work.

This is a simplified version of Nikola Stojiljković's answer

Related