示例#1
0
 /**
  * Parse the given string as a function call.  That is, it has the format 'functionName(arg1, arg2, ...)' where
  * the argument list is parsed by the parseArguments() method.
  *
  * @param string $call Function call to parse.
  *
  * @return array
  * @throws \InvalidArgumentException
  */
 public static function parseFunctionCall($call)
 {
     $matches = array();
     if (preg_match(self::REGEX_FUNCTION_CALL, $call, $matches) && sizeof($matches) > 1) {
         return array('name' => $matches[1], 'arguments' => sizeof($matches) > 2 ? self::parseArguments($matches[2]) : array());
     } else {
         throw new \InvalidArgumentException(sprintf('Cannot parse function call [%s] not of the format name(arg1, arg2, ..)', TypeUtilities::describe($call)));
     }
 }
示例#2
0
 /**
  * Determine the argument list for the given callable method, depending on the given values.  This allows for a
  * combination of fixed values, type hinting detection, and declared defaults.
  *
  * The fixed values are used first.  These are required arguments that are assumed to exist in any implementation,
  * in the order given.  This is effectively the starting point for the resulting argument list.
  *
  * When all the fixed values are exhausted, the remaining values are filled by first checking the type against each
  * of the given typed values.  Any matching typed value ias appended to the resulting argument list.  Typed values
  * are used once only.  If there are multiple arguments of the same type, then two values should be supplied in the
  * typed values argument list.
  *
  * If there is no matching typed value, then the remaining values will be used.  When the remaining values are
  * exhausted, then the parameter's default value will be used.
  *
  * If any parameter has no matching typed arguments, and there are no fixed values or remaining values left to
  * process, and does not have a default value, then a runtime exception is issued.
  *
  * @param callable|\ReflectionMethod|\Closure|object|string $callable Method or function reference, name or
  *   reflection.
  * @param array|null $fixedValues Values that are required at the start of the argument list.  These will be used
  *   before any other values in determining the argument list.  If there are more elements than the number of
  *   arguments specified by the callable, then not all elements will be used.
  * @param array|null $typedValues Values that are detected by type hinting.  Not all these values are necessarily
  *   used, only those that are matched by type against the callable's argument list.
  * @param array|null $remainingValues Values that are used when all the fixed values are used, and there are no
  *   matching typed values.  Remaining values are used in preference to the parameter default values.
  *
  * @return array Array of arguments to pass to the method call, e.g. using call_user_fuc_array().
  *
  * @throws \RuntimeException If there are insufficient matching values provided to pass for all required arguments.
  */
 public static function getArguments($callable, array $fixedValues = null, array $typedValues = null, array $remainingValues = null)
 {
     $arguments = array();
     foreach ($parameters = self::getParameters($callable) as $parameterIndex => $parameter) {
         if (sizeof($fixedValues) > 0) {
             $arguments[] = array_shift($fixedValues);
         } else {
             $matchedParameter = false;
             foreach ($typedValues ?: array() as $typedValueIndex => $typedValue) {
                 if ($matchedParameter === false && $parameter->getClass() && $parameter->getClass()->isInstance($typedValue)) {
                     $matchedParameter = $typedValueIndex;
                 }
             }
             if ($matchedParameter !== false) {
                 $match = array_splice($typedValues, $matchedParameter, 1);
                 $arguments[] = $match[0];
             } else {
                 if (!empty($remainingValues)) {
                     $arguments[] = array_shift($remainingValues);
                 } elseif ($parameter->isDefaultValueAvailable()) {
                     $arguments[] = $parameter->getDefaultValue();
                 } else {
                     throw new \RuntimeException(sprintf('TypeUtilities cannot determine arguments for callable [%s] based on supplied values: %d unhandled parameters and %d arguments processed', TypeUtilities::describe($callable), sizeof($parameters) - $parameterIndex, sizeof($arguments)));
                 }
             }
         }
     }
     return $arguments;
 }