Передача массива объектов по ссылке на метод - PullRequest
3 голосов
/ 17 ноября 2010

В моем классе есть метод, который принимает объект по ссылке.Он украшает этот объект для расширения функциональности.

в основном ...

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 ]

4 голосов
/ 17 ноября 2010

РЕДАКТИРОВАТЬ: другое решение, о котором я могу подумать, - это переназначить ваши локальные объекты на элементы массива, например:

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

Ваши объекты decorator и test работают с одним и тем же объектом в вашем массиве, поэтому выгрузка $a из вашего вызывающего кода приводит к созданию декорированного объекта.

В настоящее время единственный способ заставить PHP изменить ваш объект, это передать его по ссылке на ваш массив, например:

$a = array( &$std );

Конечно, это будет довольно хакерское решение, которое может не соответствовать вашим потребностям.

1 голос
/ 17 ноября 2010

Я думаю, что проблема foreach( $objects as $object ). Эта конструкция превратит копию элементов массива в $object. Вам нужно сделать foreach( $objects as & $object ).

foreach в руководстве по PHP

...