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

发布于 2024-10-03 01:30:46 字数 793 浏览 3 评论 0原文

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

基本上...

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

I have a method in my class that accepts an object by reference. It decorates that object to extend the functionality.

basically...

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

I'm trying to write a convenience method addObjects() but it's not changing $object

This does not work...

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

I've tried a bunch of other routes but none have worked. I'm sure there's a way to do this, but it's escaping me. Maybe i've been staring at my computer too long.

Here's is a live example

http://ideone.com/tfopZ


Update

It seems there's no way other than to pass references when creating the array of objects

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼藏柔 2024-10-10 01:30:46

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

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

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

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

)

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

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

$a = array( $std );

因此您有两个对该对象的引用:

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

它解释了为什么打印 $std 会为您提供与未修饰相同的对象,因为您正在查看 $std 它被创建时 这里,它与数组中包含的对象不同:

$std = new StdClass;

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

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

$a = array( &$std );

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

EDIT: another solution I can think of is to reassign your local objects to the array elements, like this:

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

Now $std is a reference to the decorated object.

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

)

I don't have a practical solution yet, but I think I can explain the behavior.

This happens because object references are passed by value by default. So in your example, the array actually contains a new reference to the object:

$a = array( $std );

So you have two references to the object:

  1. One created as you initialize the object, and
  2. One owned by the array.

It explains why printing $std gives you the same object as if it hadn't been decorated, because you are looking at $std as it was created here, which isn't the same as the one contained in the array:

$std = new StdClass;

Your decorator and test objects are working with the same object in your array, which is why dumping $a from your calling code produces the decorated object.

Currently the only way I can think of to coax PHP into modifying your object, is to pass it by reference to your array, like this:

$a = array( &$std );

Of course, that'll probably be a rather hacky solution and may not suit your needs.

三月梨花 2024-10-10 01:30:46

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

PHP 手册中的 foreach

I think the problem is foreach( $objects as $object ). This construction will make a copy of the array elements into $object. You need to do foreach( $objects as & $object ).

foreach in the PHP manual

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文