2008/7/26 David Zülke <[EMAIL PROTECTED]>
> Am 22.07.2008 um 16:37 schrieb Richard Quadling:
>
> Actually, would allowing PHP to skip defaulted parameters be a better
>> facility to add?
>>
>> function foo($opt1 = Null, $opt2 = Null){}
>>
>> foo(,True);
>>
>> Hmm. Doesn't look good does it. But, useful. Having to supply the default
>> value if you don't want to override the default is sort of
>> counter-intuitive. Suppling nothing should equal the default value.
>>
>
> That would be totally brilliant, since it means that one wouldn't have to
> know the default value in order to skip an argument.
>
> We looked into this a couple of months ago and the info I got from the
> engineer that dug into the code was that it would be relatively complicated
> to implement in the engine (we were considering a keyword back then, sth
> like foo(default, true);).
>
> But if it can be done... I'm all for it. It's definitely useful.
>
> David
>
>
Since the inception of SPL, you can use a combination of func_get_args and
reflection to gather all the params that the function will use (be they ones
that have been supplied or default ones).
So, the components are there. I just don't have the C skills to merge these
two facilities. I think there needs to be another internal type though. To
differentiate between a userland NULL being supplied nothing being supplied
(VOID ?)
I use this userland function to gather all the parameters.
function getArgs($s_FunctionOrMethod, array $a_SuppliedParams = array()) {
$a_Arguments = array();
// Determine if we are examining a function or a method.
// As function names cannot contain ::, we should be OK with this.
list($s_Class, $s_Method) = split('::', $s_FunctionOrMethod);
if (function_exists($s_FunctionOrMethod) || method_exists($s_Class,
$s_Method)) {
// Create the appropriate reflector.
if (function_exists($s_FunctionOrMethod)) {
$rf_This = new ReflectionFunction($s_FunctionOrMethod);
} else {
$rf_This = new ReflectionMethod($s_Class, $s_Method);
}
// Shortcut the counts and the parameters.
$i_Supplied = count($a_SuppliedParams);
$i_Declared = $rf_This->getNumberOfParameters();
$a_Params = $rf_This->getParameters();
// Process the largest number (either Supplied or Declared)
for ($i_Arg = 0, $i_Args = max($i_Supplied, $i_Declared) ; $i_Arg <
$i_Args ; ++$i_Arg) {
// Is this is a Declared param?
if ($i_Arg < $i_Declared) {
// Determine the parameter name.
$s_ParamName = $a_Params[$i_Arg]->getName();
// Get the Default value.
if ($a_Params[$i_Arg]->isDefaultValueAvailable()) {
$a_Arguments[$s_ParamName] =
$a_Params[$i_Arg]->getDefaultValue();
}
// Overwrite with the Supplied value if it exists.
if ($i_Arg < $i_Supplied) {
$a_Arguments[$s_ParamName] = $a_SuppliedParams[$i_Arg];
}
// Otherwise this is a Supplied param without a declaration.
} else {
// Add the Supplied param to the results.
$a_Arguments[] = $a_SuppliedParams[$i_Arg];
}
}
}
return $a_Arguments;
}
I use this as ...
$a_Args = getArgs(__METHOD__, func_get_args());
inside the method of function. I rely on the fact that __METHOD__ returns
something sensible when used in a function.
It wouldn't work as is if missed params were allowed. But if func_get_args()
returned the params keyed to the params position, the gaps in the index/key
would signify a missed param.
I hope one of the core-devs sees this.
Richard.
--
-----
Richard Quadling
Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&r=213474731
"Standing on the shoulders of some very clever giants!"