如何在PHP中使用反射通过引用获得一个属性值



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

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是原始数组的副本。

提前感谢!

从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://3v4l.org/sZMt1

找到一个运行的示例

我实际上在http://ocramius.github.io/blog/accessing-private-php-class-members-without-reflection/

详细解释了该技术和最终用例。

恐怕不行。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从回调中调用它。一旦在原始类中定义了这个方法,它就可以访问所有的私有成员。

相关内容

  • 没有找到相关文章

最新更新