/** * Helper method to retrieve the name of a ReflectionFunctionAbstract * @param \ReflectionFunctionAbstract $reflection * @return string */ protected function getReflectionFunctionName(\ReflectionFunctionAbstract $reflection) { // Class method if ($reflection instanceof \ReflectionMethod) { return $reflection->getDeclaringClass()->getName() . '::' . $reflection->getName(); } return $reflection->getName(); }
private function fetchFunctionIdentifier(\ReflectionFunctionAbstract $function) { $functionIdentifier = $function->getName(); if ($function instanceof \ReflectionMethod) { $functionIdentifier = sprintf('%s::%s', $function->getDeclaringClass()->getName(), $function->getName()); } return $functionIdentifier; }
/** * Generate key for parameter * * @param \ReflectionParameter $parameter * @param \ReflectionFunctionAbstract $method * * @return string */ public static function generateForParameter(\ReflectionParameter $parameter, \ReflectionFunctionAbstract $method) { if ($method instanceof \ReflectionMethod) { $key = $method->getDeclaringClass()->getName() . '::' . $method->getName() . ':' . $parameter->getName(); } else { $key = 'function::' . $method->getName() . ':' . $parameter->getName(); } return $key; }
private function getFunctionName(\ReflectionFunctionAbstract $reflectionFunction) { if ($reflectionFunction->isClosure()) { return sprintf('closure defined in %s at line %d', $reflectionFunction->getFileName(), $reflectionFunction->getStartLine()); } elseif ($reflectionFunction instanceof \ReflectionMethod) { return sprintf('%s::%s', $reflectionFunction->getDeclaringClass()->getName(), $reflectionFunction->getName()); } return $reflectionFunction->getName(); }
/** * Python-style args/kwargs argument arrays. Creates an indexed * argument list to use with reflection:: * * class Pants { * function doPants($arg1, $arg2, $arg3=null, $foo=>null) { * } * } * * $args = ['arg1', 'arg2', 'foo'=>'bar']; * $rm = (new ReflectionClass('Pants'))->getMethod('doPants'); * $return = $rm->invokeArgs(func_get_call_args($rm), $args); */ public static function getCallArgs(\ReflectionFunctionAbstract $rm, $args, $ignoreUnknown = false) { if (!$args) { $args = []; } $callArgs = []; $inArgs = true; foreach ($rm->getParameters() as $idx => $param) { $paramFound = false; if ($inArgs && ($inArgs = isset($args[$idx]))) { $callArgs[] = $args[$idx]; $paramFound = true; unset($args[$idx]); } else { if (array_key_exists($param->name, $args)) { $paramFound = true; $callArgs[] = $args[$param->name]; unset($args[$param->name]); } } if (!$paramFound) { if ($param->isDefaultValueAvailable()) { $callArgs[] = $param->getDefaultValue(); } else { throw new \UnexpectedValueException("No value for argument {$param->name} for function {$rm->getName()}"); } } } if ($args && !$ignoreUnknown) { throw new \UnexpectedValueException("Unknown keyword arguments: " . implode(", ", array_keys($args))); } return $callArgs; }
/** * Print the signature of the target action. * * @return string */ public function __toString() { if ($this->target instanceof \ReflectionMethod) { return sprintf('%s->%s()', $this->target->getDeclaringClass()->name, $this->target->name); } if ($this->target instanceof \ReflectionFunction && !$this->target->isClosure()) { return $this->target->getName() . '()'; } return '*closure*'; }
/** * {@inheritdoc} */ public function getInvocations(\ReflectionFunctionAbstract $function) { $result = []; foreach ($this->availableInvocations($function->getName()) as $invocation) { if ($this->isTargeted($invocation, $function)) { $result[] = $invocation; } } return $result; }
/** * @param \ReflectionParameter $parameter * @param \ReflectionFunctionAbstract $context */ public function __construct(\ReflectionParameter $parameter, \ReflectionFunctionAbstract $context) { $this->parameter = $parameter; $this->context = $context; $name = $context->getName(); if ($context instanceof \ReflectionMethod) { $name = $context->class . '::' . $name; } parent::__construct("Unable to resolve '{$parameter->name}' argument in '{$name}'."); }
/** * Generates list of arguments using autowiring. * @return array */ public static function autowireArguments(\ReflectionFunctionAbstract $method, array $arguments, $container) { $optCount = 0; $num = -1; $res = array(); $methodName = ($method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' : '') . $method->getName() . '()'; foreach ($method->getParameters() as $num => $parameter) { if (array_key_exists($num, $arguments)) { $res[$num] = $arguments[$num]; unset($arguments[$num]); $optCount = 0; } elseif (array_key_exists($parameter->getName(), $arguments)) { $res[$num] = $arguments[$parameter->getName()]; unset($arguments[$parameter->getName()]); $optCount = 0; } elseif (($class = PhpReflection::getParameterType($parameter)) && !PhpReflection::isBuiltinType($class)) { $res[$num] = $container->getByType($class, FALSE); if ($res[$num] === NULL) { if ($parameter->allowsNull()) { $optCount++; } elseif (class_exists($class) || interface_exists($class)) { $rc = new \ReflectionClass($class); if ($class !== ($hint = $rc->getName())) { throw new ServiceCreationException("Service of type {$class} needed by {$methodName} not found, did you mean {$hint}?"); } throw new ServiceCreationException("Service of type {$class} needed by {$methodName} not found. Did you register it in configuration file?"); } else { throw new ServiceCreationException("Class {$class} needed by {$methodName} not found. Check type hint and 'use' statements."); } } else { if ($container instanceof ContainerBuilder) { $res[$num] = '@' . $res[$num]; } $optCount = 0; } } elseif ($parameter->isOptional() || $parameter->isDefaultValueAvailable()) { // !optional + defaultAvailable = func($a = NULL, $b) since 5.3.17 & 5.4.7 // optional + !defaultAvailable = i.e. Exception::__construct, mysqli::mysqli, ... $res[$num] = $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : NULL; $optCount++; } else { throw new ServiceCreationException("Parameter \${$parameter->getName()} in {$methodName} has no class type hint or default value, so its value must be specified."); } } // extra parameters while (array_key_exists(++$num, $arguments)) { $res[$num] = $arguments[$num]; unset($arguments[$num]); $optCount = 0; } if ($arguments) { throw new ServiceCreationException("Unable to pass specified arguments to {$methodName}."); } return $optCount ? array_slice($res, 0, -$optCount) : $res; }
/** * @return array */ public static function combineArgs(\ReflectionFunctionAbstract $method, $args) { $res = array(); $i = 0; foreach ($method->getParameters() as $param) { $name = $param->getName(); if (isset($args[$name])) { // NULLs are ignored $res[$i++] = $args[$name]; $type = $param->isArray() ? 'array' : ($param->isDefaultValueAvailable() ? gettype($param->getDefaultValue()) : 'NULL'); if (!self::convertType($res[$i - 1], $type)) { $mName = $method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' . $method->getName() : $method->getName(); throw new BadRequestException("Invalid value for parameter '{$name}' in method {$mName}(), expected " . ($type === 'NULL' ? 'scalar' : $type) . "."); } } else { $res[$i++] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : ($param->isArray() ? array() : null); } } return $res; }
function getFunctionString(ReflectionFunctionAbstract $ref) { $name = $ref->getName() . '('; if ($ref instanceof ReflectionMethod) { if ($ref->isStatic()) { $name = '::' . $name; } else { $name = '->' . $name; } } $name .= getParamString($ref); $name .= ')'; return $name; }
/** * @param \ReflectionFunctionAbstract $functionOrMethod */ private function processFunctionOrMethod(\ReflectionFunctionAbstract $functionOrMethod) { if ($functionOrMethod->isInternal()) { return; } $name = $functionOrMethod->getName(); if ($functionOrMethod instanceof \ReflectionMethod) { $name = $functionOrMethod->getDeclaringClass()->getName() . '::' . $name; } if (!isset($this->lookupTable[$functionOrMethod->getFileName()])) { $this->lookupTable[$functionOrMethod->getFileName()] = []; } foreach (range($functionOrMethod->getStartLine(), $functionOrMethod->getEndLine()) as $line) { $this->lookupTable[$functionOrMethod->getFileName()][$line] = $name; } }
public static function addRoute($method, $path, $object, ReflectionFunctionAbstract $reflection) { if (!isset(self::$routes[$method])) { self::$routes[$method] = array(); } if (!isset(self::$routes[$method][$path])) { self::$routes[$method][$path] = array(); } self::$routes[$method][$path][] = array('method' => $reflection, 'object' => $object, 'class' => get_class($object), 'name' => $reflection->getName()); }
/** * Get called method from abstract reflection function * * @param \ReflectionFunctionAbstract $method * @param bool $closureInfo * * @return string */ public static function getCalledMethod(\ReflectionFunctionAbstract $method, $closureInfo = true) { if ($method->isClosure()) { if ($closureInfo) { return sprintf('Closure [%s:%d]', $method->getFileName(), $method->getStartLine()); } return 'Closure'; } if ($method instanceof \ReflectionMethod) { return sprintf('%s::%s', $method->getDeclaringClass()->getName(), $method->getName()); } return $method->getName(); }
/** * @return array */ public static function combineArgs(\ReflectionFunctionAbstract $method, $args) { $res = array(); foreach ($method->getParameters() as $i => $param) { $name = $param->getName(); list($type, $isClass) = self::getParameterType($param); if (isset($args[$name])) { $res[$i] = $args[$name]; if (!self::convertType($res[$i], $type, $isClass)) { throw new BadRequestException(sprintf('Argument $%s passed to %s() must be %s, %s given.', $name, ($method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' : '') . $method->getName(), $type === 'NULL' ? 'scalar' : $type, is_object($args[$name]) ? get_class($args[$name]) : gettype($args[$name]))); } } elseif ($param->isDefaultValueAvailable()) { $res[$i] = $param->getDefaultValue(); } elseif ($type === 'array') { $res[$i] = array(); } elseif ($type === 'NULL' || $isClass) { $res[$i] = NULL; } else { throw new BadRequestException(sprintf('Missing parameter $%s required by %s()', $name, ($method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' : '') . $method->getName())); } } return $res; }
/** * @param string $messageFormat * @param \ReflectionFunctionAbstract $reflection * * @return self */ public static function invalidFunctionMessage($messageFormat, \ReflectionFunctionAbstract $reflection) { return self::construct(array_merge(['Invalid function %s defined in %s lines %d-%d: ' . $messageFormat, $reflection->getName(), $reflection->getFileName(), $reflection->getStartLine(), $reflection->getEndLine()], array_slice(func_get_args(), 2))); }
/** * @return array */ public static function combineArgs(\ReflectionFunctionAbstract $method, $args) { $res = []; $i = 0; foreach ($method->getParameters() as $param) { $name = $param->getName(); if (!isset($args[$name]) && $param->isDefaultValueAvailable()) { $res[$i++] = $param->getDefaultValue(); } else { $res[$i++] = $arg = isset($args[$name]) ? $args[$name] : NULL; list($type, $isClass) = self::getParameterType($param); if (!self::convertType($arg, $type, $isClass)) { throw new BadRequestException(sprintf('Argument $%s passed to %s() must be %s, %s given.', $name, ($method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' : '') . $method->getName(), $type === 'NULL' ? 'scalar' : $type, is_object($arg) ? get_class($arg) : gettype($arg))); } } } return $res; }
/** * Get a human-readable name from a reflected callable. * * @param \ReflectionFunctionAbstract $ref * @return string */ protected function getCallableName(\ReflectionFunctionAbstract $ref) { if ($ref instanceof \ReflectionMethod) { return $ref->getDeclaringClass()->name . '->' . $ref->name . '()'; } if ($ref->isClosure()) { return '*closure*'; } return $ref->getName() . '()'; }
/** * @param \ReflectionFunctionAbstract $method * @param array $args * @return array * @throws BadRequestException */ protected function combineArgs(\ReflectionFunctionAbstract $method, array $args) { $res = array(); $i = 0; foreach ($method->getParameters() as $param) { $name = $param->getName(); if (isset($args[$name])) { $res[$i++] = $args[$name]; } elseif (isset($args[$i])) { $value = $args[$i]; $res[$i++] = $value; } else { $res[$i++] = $param->isDefaultValueAvailable() && $param->isOptional() ? $param->getDefaultValue() : ($param->isArray() ? array() : NULL); } $type = $param->isArray() ? 'array' : ($param->isDefaultValueAvailable() && $param->isOptional() ? gettype($param->getDefaultValue()) : 'NULL'); if (!$this->convertType($res[$i - 1], $type)) { $mName = $method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' . $method->getName() : $method->getName(); throw new BadRequestException("Invalid value for parameter '{$name}' in method {$mName}(), expected " . ($type === 'NULL' ? 'scalar' : $type) . "."); } } return $res; }
/** Returns the type-hints of the parameters of a given function. @param $oFunction The function to scan. @return array(string) An associative array mapping parameters' names to their type-hint. */ public static function getParametersTypeHints(ReflectionFunctionAbstract $oFunction) { $bArg = true; $bFunctionName = false; $iLevel = 0; $bInPrototype = false; $sHint = null; $aHints = array(); $oFile = new SplFileObject($oFunction->getFileName()); $oFile->seek($oFunction->getStartLine() - 1); while ($oFile->valid()) { $aTokens = token_get_all('<?php ' . $oFile->current() . ' */'); $iCount = count($aTokens); for ($i = 0; $i < $iCount; ++$i) { if ($bInPrototype) { if (is_array($aTokens[$i]) && $bArg == true) { switch ($aTokens[$i][0]) { case T_STRING: case T_ARRAY: $sHint = $aTokens[$i][1]; break; case T_VARIABLE: if ($sHint !== null) { $aHints[substr($aTokens[$i][1], 1)] = $sHint; } $bArg = false; $sHint = null; } } elseif ($aTokens[$i] == '(') { ++$iLevel; } elseif ($aTokens[$i] == ')') { if (--$iLevel == 0) { break 2; } } elseif ($iLevel == 1 && $aTokens[$i] == ',') { $bArg = true; } } elseif (is_array($aTokens[$i])) { switch ($aTokens[$i][0]) { case T_FUNCTION: $bFunctionName = true; break; case T_STRING: if ($bFunctionName) { if ($aTokens[$i][1] == $oFunction->getName()) { $bInPrototype = true; } else { $bFunctioName = false; } } } } } $oFile->next(); } return $aHints; }
/** * Create a string representation of the method signature. * * @param ReflectionFunctionAbstract $func The function you want a signature for. * @return void **/ public static function makeFunctionSignature(ReflectionFunctionAbstract $func) { $signature = $func->getName() . '( '; foreach ($func->getParameters() as $param) { $signature .= '$' . $param->getName(); if ($param->isDefaultValueAvailable()) { $signature .= ' = ' . var_export($param->getDefaultValue(), true); } $signature .= ', '; } if ($func->getNumberOfParameters() > 0) { $signature = substr($signature, 0, -2); } $signature .= ' )'; return $signature; }