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

Php 通过引用将对象数组传递给方法,php,arrays,object,pass-by-reference,Php,Arrays,Object,Pass By Reference,我的类中有一个通过引用接受对象的方法。它装饰该对象以扩展功能 基本上 public function addObject( &$object ) { $object = $this->decorate( $object ); } 我试图编写一个方便的方法addObjects(),但它没有改变$object 这不管用 public function addObjects( array &$objects ) { foreach( $objects as $o

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

基本上

public function addObject( &$object ) {
    $object = $this->decorate( $object );
}
我试图编写一个方便的方法
addObjects()
,但它没有改变
$object

这不管用

public function addObjects( array &$objects ) {
    foreach( $objects as $object ) {
        $this->addObject( $object );
    }
}
我尝试过很多其他的路线,但都没有成功。我肯定有办法做到这一点,但我还是逃避不了。也许我盯着电脑看太久了

下面是一个活生生的例子


更新 在创建对象数组时,除了传递引用之外,似乎没有其他方法了

$objects = array( &$object1, $object2 ); //object1 will be decorated, object2 will not
$thing->addObjects( $objects );

我认为问题在于
foreach($objects作为$object)
。此构造将把数组元素复制到
$object
中。您需要执行foreach($objects as&$object)


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

$dec->addObjects( $a);
$std = $a[0];
print_r( $std );
$a = array( &$std );
现在,
$std
是对装饰对象的引用

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

)

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

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

$a = array( $std );
因此,您有两个对对象的引用:

$a = array( $std );
  • 初始化对象时创建的一个,以及
  • 阵列拥有的一个
  • 它解释了为什么打印
    $std
    会像未装饰一样为您提供相同的对象,因为您看到的是在此处创建的
    $std
    ,它与数组中包含的对象不同:

    $std = new StdClass;
    
    您的
    decorator
    test
    对象正在使用数组中的同一对象,这就是为什么从调用代码中转储
    $a
    会生成修饰对象

    decorator Object
    (
        [decoratee:protected] => stdClass Object
            (
            )
    
    )
    
    目前,我能想到的诱使PHP修改对象的唯一方法是通过引用将其传递给数组,如下所示:

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

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

    如果您在函数中设置
    $objects=NULL
    ,然后在函数返回后设置
    var\u dump()
    ,会发生什么?我刚刚编辑了答案以包含另一个解决方案。不那么麻烦,但是你需要重新分配你的变量。好的,这是我的PHPV4回退版本:
    foreach($objects as$i=>$na){$object=&$objects[i]
    这确实有效,所以这肯定是原因,但你是对的。这有点不太正常。我仍在寻找更好的方法。我尝试使用
    func\u get\u args()删除数组并添加无限对象。
    但也没有运气