【问题标题】:Passing an array of objects by reference to a method通过引用方法传递对象数组
【发布时间】:2011-05-11 05:04:33
【问题描述】:

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

基本上...

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

【问题讨论】:

  • 如果在函数中设置$objects = NULL,然后在函数返回后设置var_dump()会怎样?
  • 我刚刚编辑了我的答案以包含另一个解决方案。不那么老套,但您需要重新分配变量。

标签: php arrays object pass-by-reference


【解决方案1】:

我认为问题出在foreach( $objects as $object )。这种构造会将数组元素复制$object。你需要做foreach( $objects as & $object )

foreach in the PHP manual

【讨论】:

  • 好的,这是我的 PHP v4 后备版本:foreach( $objects as $i => $na ) { $object = & $objects[i];
【解决方案2】:

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

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

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

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

)

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

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

$a = array( $std );

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

  1. 在初始化对象时创建一个,并且
  2. 数组拥有的一个。

它解释了为什么打印 $std 给你的对象就像它没有被装饰一样,因为你看到的是 $std 因为它是在这里创建的,这不是与数组中包含的相同:

$std = new StdClass;

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

目前我能想到的哄 PHP 修改你的对象的唯一方法是通过引用你的数组来传递它,像这样:

$a = array( &$std );

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

【讨论】:

  • 这确实有效,所以这绝对是原因,但你是对的,它有点 hacky。我还在寻找更好的方法。我尝试使用func_get_args() 删除数组并添加无限对象,但也没有运气
猜你喜欢
  • 2012-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-11
  • 2021-09-11
  • 2011-07-06
相关资源
最近更新 更多