Массивы PHP и сквозные ссылки

В PHP использовался следующий шаблон:

function foo($arr)
{
    // modify $arr in some way
    return $arr;
}

Затем это можно было бы вызвать с использованием значения pass-by-value:

$arr = array(1, 2, 3);
$newarr = foo($arr);

или по ссылке:

$arr = array(1, 2, 3);
foo(&$arr);

но "Переадресация времени звонка устарела". Изменение сигнатуры функции:

function foo(&$arr)

будет обрабатывать случай передачи по ссылке, но нарушит двухцелевой характер исходной функции, поскольку пропускная способность больше невозможна.

Есть ли способ обойти это?

Ответ 1

Я думаю, что это как можно ближе:

function foo(&$bar) { ... }

foo($array);                // call by reference
$bar = foo($_tmp = $array); // call by value

К сожалению, для каждого вызова потребуются некоторые изменения.

Ответ 2

Духовная природа была глупой, поэтому поведение устарело. Измените подпись функции, как вы предлагаете.

Ответ 3

К сожалению, я не верю, что вокруг есть способ.

Просто сделайте свою функцию ссылкой с &.

Ответ 4

Простым обходным путем является подготовка оберточной функции:

function foo($arr) {
    return foo_ref($arr);
}

function foo_ref(&$arr) {
    ...

Затем, в зависимости от текущего использования, вызовите обычный foo() или foo_ref(), если вы хотите, чтобы массив был изменен на месте.


Существует также общий чит параметра array(&$wrap), но это не кажется вам подходящим в вашем случае. Более сложным обходом может стать этот сложный трюк:

// pass by value
foo($array);

// pass by reference (implicitly due to being an object)
foo($array = new ArrayObject($array));

Это позволяет аналогичное обращение к неподготовленным функциям. Лично я предпочел бы сохранить предупреждение E_DEPRECATED и предполагаемый синтаксис для этой цели.