Списки аргументов переменной-длины by-ref в функциях - PullRequest
4 голосов
/ 07 октября 2011

В PHP вы можете сделать это:

function something() {
  foreach (func_get_args() as $arg)
    echo $arg;
}
something(1, 3); //echoes "13"

Это нормально работает для аргументов, передаваемых по значению, но что, если я хочу, чтобы они передавались по ссылке? как это:

function something_else() {
  foreach (func_get_args() as $arg)
    $arg *= 2;
}
$a = 1;
$b = 3;
something_else($a, $b);
echo $a . $b; //should echo "26", but returns "13" when I try it

Возможно ли это в PHP?

Ответы [ 3 ]

2 голосов
/ 07 октября 2011

Вопрос кажется ужасным, но давай позабавим тебя. Ниже приведен ужасный хак , но вы можете отправить один аргумент, содержащий элементы, с которыми вы хотите работать.

function something_else($args) {
    foreach ($args as &$arg) {
        $arg *= 2;
    }
}
$a = 1;
$b = 3;
something_else(array(&$a, &$b));
echo $a . $b; // 26
1 голос
/ 07 октября 2011

Вы можете сделать это таким образом, но он использует передачу по времени вызова по ссылке, которая устарела в PHP 5.3:

function something_else() {
    $backtrace = debug_backtrace();
    foreach($backtrace[0]['args'] as &$arg)
    $arg *= 2;
}
$a = 1;
$b = 3;
something_else(&$a, &$b);
echo $a . $b;
1 голос
/ 07 октября 2011

Нет. Ты не можешь. Объявление параметра, переданного с помощью ref, является явным как function something(&$arg1, &$arg2). Если вы не знаете количество параметров во время компиляции, вы можете сделать что-то вроде этого:

function something_else($args) {
      foreach ($args as $arg)
        $GLOBALS[$arg] *= 2;
}
$a = 1;
$b = 3;
something_else(array('a', 'b'));
echo $a . $b; //returns "26"

В основном, код передает функции имена параметров, которые функция будет изменять. $GLOBALS содержит ссылки на все определенные переменные в глобальной области видимости скрипта. Это означает, что если вызов из другой функции, он не будет работать:

function something_else($args) {
      foreach ($args as $arg)
        $GLOBALS[$arg] *= 2;
}

function other_function(){
    $a = 1;
    $b = 3;
    something_else(array('a', 'b'));
    echo $a . $b; //returns "13"
}
other_function();

вызывает уведомления о неопределенных индексах a и b. Поэтому другой подход заключается в создании массива со ссылками на переменные, которые функция будет изменять как:

function something_else($args) {
      foreach ($args as &$arg)
        $arg *= 2;
}

function other_fucntion(){
    $a = 1;
    $b = 3;
    something_else(array(&$a, &$b));
    echo $a . $b; //returns "26"
}
other_fucntion();

Обратите внимание на & в строке foreach. Это необходимо, чтобы не создавать новую переменную, повторяющуюся в массиве. PHP> 5 необходим для этой функции.

...