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 &argx
s, 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
}
精彩评论