как передать неограниченное количество аргументов по ссылке в php - PullRequest
12 голосов
/ 11 августа 2011

У меня есть функция php, у которой есть неограниченное количество аргументов, которые я получаю от func_get_args ().У меня есть некоторые операции с аргументами (изменение строки или что-то делать), и я хочу, чтобы это было похоже на передачу аргумента по ссылке.это возможно?

пример:

$test = 'foo';
$test2 = 'bar';

function test(){
    $args = func_get_args();
    foreach($args as $arg)
        $arg .= 'baz';
}

test($test, $test2);

Ответы [ 8 ]

14 голосов
/ 21 марта 2015

Начиная с PHP-5.6, вы можете использовать variadic ссылка:

function test(&...$args) {
    foreach ($args as &$arg) {
        $arg .= 'baz';
    }
}
12 голосов
/ 12 августа 2011

Как ответили в PHP: список аргументов переменной длины по ссылке? , в PHP нет способа объединить переменную длины и передать аргументы ссылочной функции.Вместо этого связанный ответ использует хак объявления 100 &argx с, а затем get_num_args(), чтобы выяснить, сколько фактически было использовано.Поздравляем, вы нашли особенно трудный угол в PHP;)

5 голосов
/ 11 августа 2011

Я очень сомневаюсь, что это возможно, но я знаю, как можно получить то, что вы хотите:

function test(&$args) {
    foreach ($args as $arg) {
        $arg .= 'baz';
    }
}

test(array(&$test, &$test2));
1 голос
/ 25 февраля 2017

Работает нормально для меня, когда делаю что-то вроде примера ниже. Я думаю, что ключ устанавливает ссылку в foreach.

$var1 = '%DIR%/test';

replaceParameters(
    $var1, 
    $var2, 
    $var3
);

function replaceParameters(&$variables) {

    $variables = array_filter(func_get_args());

    $parameters = [
        '%DIR%' => __DIR__, 
        '%FILE%' => __FILE__,
    ];

    foreach($variables as &$variable) {
        $variable = str_replace(array_keys($parameters), array_values($parameters), $variable);
    }

}
1 голос
/ 12 августа 2011

Это работает:

$test = 'foo';
$test2 = 'bar';

function test(){
    $backtrace = debug_backtrace();
    foreach($backtrace[0]['args'] as &$arg)
        $arg .= 'baz';
}

test(&$test, &$test2);

Однако при этом используется передача времени вызова по ссылке, которая не рекомендуется.

0 голосов
/ 11 июля 2015
function byref_alias()
{
 //$argz=func_get_args(); //byval, not what you want
 $argz=debug_backtrace()[0]['args']; //byref hack
 $argz[0]++; works
}
0 голосов
/ 05 сентября 2014

Использование объектов - это решение

class O {
    public $v;
    public function __construct(&$p){
        $this->v = &$p;
    }
}

function append_baz_to_all(){
    foreach(func_get_args() as &$arg){
        $arg->v .= 'baz';
    }
}

function test1(){
    echo "test1\n";
    $a='A';$b='B';$c='C';$d='D';$e='E';$f='F';$g='G';
    echo("\$a=$a \$b=$b \$c=$c \$d=$d \$e=$e \$f=$f \$g=$g\n");
    append_baz_to_all(new O($a), new O($b));
    echo("\$a=$a \$b=$b \$c=$c \$d=$d \$e=$e \$f=$f \$g=$g\n\n");
}

//shortcutting
function o(&$v){return new O($v);}

function test2(){
    echo "test2\n";
    $a='A';$b='B';$c='C';$d='D';$e='E';$f='F';$g='G';
    echo("\$a=$a \$b=$b \$c=$c \$d=$d \$e=$e \$f=$f \$g=$g\n");
    append_baz_to_all(o($c), o($d), o($e));
    echo("\$a=$a \$b=$b \$c=$c \$d=$d \$e=$e \$f=$f \$g=$g\n\n");
}


test1();
test2();
0 голосов
/ 07 апреля 2014

Мне тоже нужна была эта функциональность, я нашел решение.

function sayhello($params) {
    //params hold an unlimited amount of references
}

sayhello([&$one, &$two]);

Хотя это зависит от php> = 5.4.Если вы используете <= 5.4, используйте синтаксис array () вместо []. </p>

Мне нравится [], но гораздо лучше:)

...