代码之家  ›  专栏  ›  技术社区  ›  Galen

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

  •  3
  • Galen  · 技术社区  · 14 年前

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

    基本上。。。

    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 回复  |  直到 14 年前
        1
  •  4
  •   BoltClock Alan H.    14 年前

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

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

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

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

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

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

    $a = array( $std );
    

    所以有两个对象引用:

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

    它解释了为什么打印 $标准 给你一样的东西,就像它没有被装饰一样,因为你在看 $标准 当它被创造时 这里,它与数组中包含的不同:

    $std = new StdClass;
    

    你的 decorator test 对象与数组中的同一对象一起工作,这就是转储 $a 从调用代码生成修饰对象。

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

    $a = array( &$std );
    

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

        2
  •  1
  •   staticsan    14 年前

    我想问题是 foreach( $objects as $object ) . 这个建筑将 复制 数组元素的 $object . 你必须这么做 foreach( $objects as & $object ) .

    foreach in the PHP manual