如何在PHP中使用反射通过引用获取属性值?

如何在PHP中使用反射通过引用获取属性值?,php,reflection,Php,Reflection,假设您有一个这样声明的类: class DummyObject{ public $attr; public function __construct(){ $this->attr=array('val_1','val_2','val_3'); } } 这样做: $obj=(new DummyObject1()); $attr=&$obj->attr; 您将获得对$attr的引用,因此在数组中进行的任何修改也将在DummyObject

假设您有一个这样声明的类:

class DummyObject{
    public $attr;
    public function __construct(){
        $this->attr=array('val_1','val_2','val_3');
    }
}
这样做:

$obj=(new DummyObject1());
$attr=&$obj->attr;
您将获得对
$attr
的引用,因此在数组中进行的任何修改也将在DummyObject$obj实例中进行

现在,最后一个问题。使用反射,如何获取对存储在
$attr
中的数组的引用而不是副本?。我尝试过这个,但没有成功:

$obj=(new DummyObject());
$reflector = new ReflectionObject($obj);
$reflectorProperty = $reflector->getProperty('attr');
$propertyValue=$reflectorProperty->getValue($ref);
实际上,
$attr
是原始数组的副本


提前谢谢

恐怕你不能
ReflectionProperty::getValue
必须通过引用返回才能实现这一点,但它没有。您可以从原始$obj获取它,您可以通过“use”语句将其传递给回调

$propertyValue = $obj->{$reflectorProperty->getName()};
或者,如果您对私有成员使用公共getter/setter,您可以

$propertyName = $reflectorProperty->getName();
$methodName = 'get' . ucfirst($propertyName);
if (method_exists($obj, $methodName)) {
    $propertyValue = call_user_func([ $object, $methodName ]);
} elseif (isset($obj->{$propertyName}) {
    $propertyValue = $this->{$propertyName};
} else {
    $propertyValue = null;
}

另一个解决方案是定义私有(或公共)方法$obj->getProperty($name),并通过反射和setAccessible从回调调用它。一旦在原始类中定义了此方法,它就可以访问所有私有成员。

由于PHP 5.4,您可以在不进行反射的情况下执行此操作:

班级厨房
{
私人$yummy=‘蛋糕’;
}
$reader=函数($object,$property){
$value=&Closure::bind(函数&()使用($property){
返回$this->$属性;
},$object,$object)->\uu invoke();
返回$value;
};
$kitchen=新厨房();
$cake=&$reader($kitchen,'yummy');
$蛋糕=‘对不起,我吃了!’;
瓦鲁垃圾场(厨房);
这要归功于PHP5.4在运行时切换闭包范围的能力

您可以在以下位置找到一个运行示例:


实际上,我在

上详细解释了该技术和最终用例,请问您的意图是什么?我的意思是,你有对象,财产名称,财产是公共的。为什么需要使用反射来获取属性?我能猜到的唯一意图是使代码复杂化。我的意图不是使代码复杂化。我有一个对象,它可以引用其他对象,这是从使用JSON_decode的JSON中的HTTP响应中获得的,我需要递归地运行所有属性,以对存储字符串的所有属性进行一些更改。可能有一种更简单的方法,可以显示JSON代码吗?我怀疑是这样。但是我注意到,
ReflectionProperty::getValue
如果该值是关联数组或其他对象,则返回引用,因此可能是以相同方式检索数组引用的一种方法。@jLu我不知道你的意思。据我所知,getValue永远不能返回引用。我尝试过使用指向对象实例和关联数组的属性,然后
ReflectionProperty::getValue
返回引用,因为可以在原始对象中看到返回对象中的更改。当属性指向数组时,此行为不同。谢谢你的关注!有什么理由让外部函数也成为闭包吗?这似乎没有必要。我只是注意到这不适用于“内部”类。明显地“警告:无法将闭包绑定到内部类ReflectionClass的作用域”,“致命错误:未捕获错误:调用null上的成员函数\uuu invoke()”