php 我可以用反射得到私有属性的值吗?

cunj1qz1  于 2023-02-28  发布在  PHP
关注(0)|答案(5)|浏览(144)

似乎不起作用:

$ref = new ReflectionObject($obj);

if($ref->hasProperty('privateProperty')){
  print_r($ref->getProperty('privateProperty'));
}

它进入IF循环,然后抛出一个错误:
属性privateProperty不存在
:|
$ref = new ReflectionProperty($obj, 'privateProperty')也不起作用...
documentation page列出了一些常量,包括IS_PRIVATE,如果我不能访问私有属性,我怎么能使用它呢?

kyks70gy

kyks70gy1#

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

更新:自PHP 8.1.0起,调用ReflectionProperty::setAccessible方法无效;默认情况下,所有属性都是可访问的。

czq61nw1

czq61nw12#

请注意,如果您需要获取来自父类的私有属性的值,则可接受的答案无效。
为此,您可以依赖getParentClass method of Reflection API
而且,这个问题已经在this micro-library中得到了解决。
更多详情请参见this blog post

jfewjypa

jfewjypa3#

getProperty抛出的是异常,不是错误,意义在于,你可以处理,给自己保存一个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();
}

要获取所有私有属性,请使用$ref->getProperties(ReflectionProperty::IS_PRIVATE);

8yoxcaq7

8yoxcaq74#

如果你需要它没有反射:

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

然后像这样(在同一个类中)使用它:

$object = new SomeObject();
$reader = $this->propertyReader();
$result = &$reader($object, 'some_property');
m3eecexj

m3eecexj5#

    • 没有**反思,你也可以
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();
    }
}

然后就像

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

应该行得通。
这是尼古拉·斯托伊利科维奇答案的简化版本

相关问题