假设你有一个这样声明的类:
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
是原始数组的副本。
提前致谢!
答案 0 :(得分:8)
从PHP 5.4开始,你可以不用反思地做到这一点:
class Kitchen
{
private $yummy = 'cake';
}
$reader = function & ($object, $property) {
$value = & Closure::bind(function & () use ($property) {
return $this->$property;
}, $object, $object)->__invoke();
return $value;
};
$kitchen = new Kitchen();
$cake = & $reader($kitchen, 'yummy');
$cake = 'sorry, I ate it!';
var_dump($kitchen);
这要归功于PHP 5.4能够在运行时切换闭包的范围。
找到正在运行的示例我实际上在http://ocramius.github.io/blog/accessing-private-php-class-members-without-reflection/
详细解释了技术和最终用例答案 1 :(得分:1)
我怕你不能。 ReflectionProperty::getValue
必须通过引用返回才能实现,但事实并非如此。
答案 2 :(得分:0)
你可以从原始的$ 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)并通过reflection和setAccessible从回调中调用它。只要在原始类中定义此方法,它就可以访问所有私有成员。