Earlier, this week, one of my co-workers was working on a personal project in which he wanted to use a function to set a variable number of parameters to zero.
[php] [/php]
His first impulse was to use func_get_args(). But this wasn't working for him. Turns out function_get_args() returns a COPY of the arguments, and not a reference. The manual didn't lean either way or the other, so I updated it.
A few mails bounced around our internal developer's list. It seems that there's no non-hack way to do this. Here's what we came up with:
Non-Solution #1
[php] $v) { $array[$k] = 0; } } $a = 1; $b = 2; $c = 3; set_array_to_zero(array(&$a, &$b, &$c)); echo "$a $b $c"; // prints "0 0 0"; ?> [/php]This WORKS, and is probably the most "proper" way to do this, but the semantics violate his original requirements.
A couple other non-semantic-repecting solutions were proposed (one using $obj = new StdClass;), but nothing that really worked the way he intended.
Here's one that seems pretty close, on the surface: Non-Solution #4
[php] [/php]Sure, it breaks semantics, again, but there's another major problem -- scope: Non-Solution #5
[php] [/php]Since there's no way to operate on an intermediate scope (only local symbols and global symbols), at least in a functional context, this approach is a dead end.
Finally, after sleeping on it, I came up with this:
Non-Solution #16
[php] [/php]This ALMOST works--I mean, it's REALLY close. The semantics are still a LITTLE off -- the $ I can live with. The @error_suppressor is also necessary, because it seems that it's not possible to pass default values to create_function(...) (try removing the @ -- you'll get (1024 - actual_number_of_arguments) error messages). There's also the issue of limiting the number of arguments to an arbitrary number. The way I see it, no developer should be working on > 1000 (actually, even that is entirely too many), anyway.
So, without resorting to eval / writing to a file + include, this is the best solution we could come up with.
Personally, I'd alter my requirements to go with the array-passing approach.
Alan Knowles
2005 Feb 13 08:49
Your friends got to much of your time to waste :)
$a = $b = $c = $d = 0;
is actually less typing, and works....
sam
2008 Jun 29 01:16
Oh, thank you.
Your solution on how to set variables to zero is amazing, and would surely be a useful one if only it were in response to something along the lines of "How do I set variables to zero" and not "How do I pass variable arguments by reference."
Thanks again.
DynV
2008 Sep 19 09:40
Great article thanks ! Boy that Alan Knowles is not a fast one ... :D
DynV
2008 Sep 19 09:49
I'd like to mention that there's a small mistake in one of your functions which follows the correct version :
function set_var_to_zero($var)
{
for ($i = 0; $i func_num_args(); $i++) {
$GLOBALS[func_get_arg($i)] = 0;
}
}
Rolf
2009 Aug 08 09:04
The following works for your requirements, as long as argument list is kept at a realistic length.
You can test it on this code pad: http://codepad.org
===========
Rolf
2009 Aug 08 09:07
I enclosed the code in php tags in my previous posts and it looks like it wasn't escaped properly. So here it is again:
[PHP]
function capitalize(ν
for ( $i=1; isset( ${"a$i"} ) and ( $arg=∨ $i++ ) {
if ( !is_null($arg) ) {
echo "a$i was:".$arg."\n";
$arg = ucwords($arg);
} else {
echo "a$i is NULL \n";
}
}
}
$one = "i am the one";
$two = "number two";
capitalize($one, $two);
echo "$one\n";
echo "$two\n";
[/PHP]
Rolf
2009 Aug 08 09:21
It still looks like the code wasnt escaped properly... apparently some trouble with the ampersand.
Email me and if you want the code.
Basically you define the function with more arguments ( passed by reference ) that you will ever need, with an incremented argument variables ($arg1, $arg2, $arg3, etc.) and with a default value of null. Then you iterate through them using variable variables : ${"arg$i"} , if the variable is set and not null, modify it and continue loop, otherwise exit loop.
It works with PHP5. Maybe earlier versions choke on setting a default value on a referenced argument (which doesn't make much sense).