通过引用方法传递对象数组

时间:2010-11-17 03:15:00

标签: php arrays object pass-by-reference

我的类中有一个方法可以通过引用接受一个对象。它装饰该对象以扩展功能。

...基本上

public function addObject( &$object ) {
    $object = $this->decorate( $object );
}

我正在尝试编写便捷方法addObjects(),但它没有改变$object

这不起作用......

public function addObjects( array &$objects ) {
    foreach( $objects as $object ) {
        $this->addObject( $object );
    }
}

我尝试了很多其他路线,但没有一条路线有效。我确信有办法做到这一点,但它正在逃避我。也许我一直盯着我的电脑。

这是一个实例

http://ideone.com/tfopZ


更新

除了在创建对象数组

时传递引用外,似乎没有别的办法
$objects = array( &$object1, $object2 ); //object1 will be decorated, object2 will not
$thing->addObjects( $objects );

2 个答案:

答案 0 :(得分:4)

编辑:我能想到的另一个解决方案是将本地对象重新分配给数组元素,如下所示:

$dec->addObjects( $a);
$std = $a[0];
print_r( $std );

现在$std是对装饰对象的引用。

decorator Object
(
    [decoratee:protected] => stdClass Object
        (
        )

)

我还没有实用的解决方案,但我想我可以解释这种行为。

这是因为默认情况下按值传递对象引用。所以在your example中,数组实际上包含对该对象的新引用:

$a = array( $std );

所以你有两个对象的引用:

  1. 在初始化对象时创建一个,
  2. 阵列拥有的一个。
  3. 它解释了为什么打印$std会为您提供与未装饰相同的对象,因为您在此处查看$std ,其中与数组中包含的内容不同:

    $std = new StdClass;
    

    您的decoratortest对象正在使用数组中的同一个对象,这就是为什么从调用代码中转储$a会生成装饰对象。

    目前我能想到的唯一方法是让PHP修改你的对象,就是通过引用将它传递给你的数组,如下所示:

    $a = array( &$std );
    

    当然,这可能是一个相当hacky的解决方案,可能不适合您的需求。

答案 1 :(得分:1)

我认为问题是foreach( $objects as $object )。此构造将数组元素的副本转换为$object。您需要foreach( $objects as & $object )

foreach in the PHP manual