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!"

Reply via email to