开发者

how to pass unlimited arguments by reference in php [duplicate]

开发者 https://www.devze.com 2023-03-27 23:06 出处:网络
This question already has answers here: PHP: variable-length argument list by reference? (5 answers) Closed 1 year ago.
This question already has answers here: PHP: variable-length argument list by reference? (5 answers) Closed 1 year ago.

I have php function that has an unlimited number of args which I am getting from func_get_args(). I have some operations with arguments (changing string or doing something) and I want this to be like a passing argument by reference. is it possible?

example:

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

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

test($test开发者_Go百科, $test2);


Since PHP-5.6 you can use a variadic reference:

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


As answered in PHP: variable-length argument list by reference?, there is no way in PHP to combine variable-length and pass by reference function arguments. Instead, the linked answer uses a hack of declaring 100 &argxs, then using get_num_args() to figure out how many were actually used. Congratulations, you found a particularly hard corner in PHP ;)

It also shows how to do it with PHP 5.6+ variadics.


I highly doubt that's possible, but I do know one way you could get what you want:

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

test(array(&$test, &$test2));


This works:

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

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

test(&$test, &$test2);

However, this uses call-time pass by reference which is deprecated.


Works fine for me when doing something like the example below. I think the key is setting the reference in the 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);
    }

}


I needed this functionality as well, I came up with a solution.

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

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

This depends on php >= 5.4 though. If you're on <= 5.4, use array() syntax instead of [].

I love [] tho, much better :)


Using objects is the solution

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


function byref_alias()
{
 //$argz=func_get_args(); //byval, not what you want
 $argz=debug_backtrace()[0]['args']; //byref hack
 $argz[0]++; works
}
0

精彩评论

暂无评论...
验证码 换一张
取 消