I’ve searched to find a way to do;
address($name = 'me');
address($street = 'fifth avenue');Which isn’t possible. So the challenge is how do you hack user defined function arguments.
This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.
The active forums are here.
July 10, 2008 6:18am
Subscribe [0]#1 / Jul 10, 2008 6:18am
I’ve searched to find a way to do;
address($name = 'me');
address($street = 'fifth avenue');Which isn’t possible. So the challenge is how do you hack user defined function arguments.
#2 / Jul 10, 2008 6:22am
You pass them as an array. 😊
#3 / Jul 10, 2008 6:26am
too much typing.
address(array('name'=>'me'))#4 / Jul 10, 2008 7:29am
perhaps use an ordering integer at the start:
address( 123, $name, $street, $city);
address( 13, $name, $city );
address( 2, $street );an example of a function that works using this might be:
function address( $order = '123' )
{
$arg_names = array( 'name', 'street', 'city' );
$args = func_get_args();
foreach( str_split( $order ) as $i=>$num ) {
$arg_name = $arg_names[ $num - 1 ];
$arg = $args[ $i + 1 ];
$$arg_name = $arg;
}
// continue as usual
}#5 / Jul 10, 2008 7:38am
Then you need to add an extra argument.
I forgot to mention that if all the arguments are present you should be able to do
address('me','fifth avenue')like you normally add arguments to the function.
#6 / Jul 10, 2008 7:55am
Another solution, similar to using array solution but with different approach:
function address()
{
foreach (func_get_args() as $arg)
{
if (preg_match('/^([a-z0-9]+):(.+)$/', $arg, $matches))
{
$$matches[1] = $matches[2];
}
}
// ...
}
address('varname1:test', 'varname2:blabla');#7 / Jul 10, 2008 8:06am
This is starting to look like my solution but you still have to add the names even if all the arguments are added.
The downside of this solution, and mine, is that it’s function bound but that is because of the func_get_args function.
Mironcho i like to add curly brackets around the variable part of the variable variable for faster detection.
#8 / Jul 10, 2008 9:36am
Well, you can set default values for arguments if you know exact number of maximum expected arguments (and if this number isn’t too big 😉 ), and then check if all arguments are presented:
function address($var1 = '', $var2 = '', $var3 = '')
{
if (func_num_args() < 3)
{
foreach (func_get_args() as $arg)
{
if (preg_match('/^([a-z0-9]+):(.+)$/', $arg, $matches))
{
${$matches[1]} = $matches[2];
}
}
}
// ...
}
address('var1:test', 'var3:blabla');
address(1, 2, 3);There are some downsides though:
- it wouldn’t be convenient, if you need to use too many arguments
- if you use the shorter calls (e.g. - address(‘var1:test’); ), the other arguments will be always defined in the function’s scope with their default values
#9 / Jul 10, 2008 9:37am
My mind can only think of something similiar to mironchos approach, except for passing key/value pairs as separate arguments, like:
function address('name', 'me', 'street', 'fifth avenue');If the first argument matches one of the argument names, treat it as key/value pairs, otherwise - just as individual arguments. It’d give a chance to pass not only strings to the function that way.
Can’t think of anything else apart from writing a short array-creating function ( function a($key, $val); ) to ease the pain a little 😛
#10 / Jul 10, 2008 9:45am
OOPS,
$person = new StdClass();
$person->name = 'me';
$person->street = 'fifth avenue';
function address($person)
{
foreach (get_object_vars($person) as $key => $value) { ... }
}I have no idea what you intend to do with the data, but anyway.
#11 / Jul 10, 2008 9:48am
to make codemole’s example work:
function address()
{
$fields = array( 'name', 'street', 'city' );
$args = func_get_args();
if( in_array( $args[0], $fields ) )
{
for( $i = 0; $i < count( $args ); i++ )
{
$key = $args[$i++];
$val = $args[$i];
$$key = $val;
}
} else
{
foreach( $fields as $i=>$field )
{
$$field = $args[$i];
}
}
// continue as before.
}#12 / Jul 10, 2008 10:41am
@mironcho : i assumed the function argument all have a default otherwise it would be an (almost?) impossible challenge. But your solution is still function bound. i’ve found a way to create a function that makes it possible to add this to all functions that could use this functionality.
@codemole : adding key value pairs as arguments doubles the argument count which is not wanted.
@wiredesignz : creating an object like in your snippet looks even uglier to me than the array solution and then the function only can accept an object. It doesn’t matter what the function does but lets say it builds a microformat marked up output.
#13 / Jul 10, 2008 10:56am
@xwero, why comment on my solution?, I gave the guy an option to consider. He will choose whichever works for him.
#14 / Jul 10, 2008 11:03am
Ah yes now i see 😊 I was beginning to think wiredesignz lost his love for little code 😊
#15 / Jul 10, 2008 11:07am
OOPS again, my bad… you are the OP, comment away. :lol: