public function enterNode(\PHPParser_Node $node) { // Determine info about the closure's location if (!$this->closureNode) { if ($node instanceof \PHPParser_Node_Stmt_Namespace) { $this->location->namespace = is_array($node->name->parts) ? implode('\\', $node->name->parts) : null; } if ($node instanceof \PHPParser_Node_Stmt_Trait) { $this->location->trait = $this->location->namespace . '\\' . $node->name; $this->location->class = null; } elseif ($node instanceof \PHPParser_Node_Stmt_Class) { $this->location->class = $this->location->namespace . '\\' . $node->name; $this->location->trait = null; } } // Locate the node of the closure if ($node instanceof \PHPParser_Node_Expr_Closure) { if ($node->getAttribute('startLine') == $this->reflection->getStartLine()) { if ($this->closureNode) { throw new \RuntimeException('Two closures were declared on the same line of code. Cannot determine ' . 'which closure was the intended target.'); } else { $this->closureNode = $node; } } } }
/** * @link http://php.net/manual/en/serializable.serialize.php */ public function serialize() { // prepare code $file = new SplFileObject($this->reflection->getFileName()); $file->seek($this->reflection->getStartLine() - 1); $code = ''; while ($file->key() < $this->reflection->getEndLine()) { $code .= $file->current(); $file->next(); } $start = strpos($code, 'function'); $code = substr($code, $start, strpos($code, '}') - $start + 1); // prepare variables $variables = []; $index = stripos($code, 'use'); // if 'use' keyword found if (false !== $index) { // get the names of the variables inside the use statement $start = strpos($code, '(', $index) + 1; $end = strpos($code, ')', $start); $use_variables = explode(',', substr($code, $start, $end - $start)); $static_variables = $this->reflection->getStaticVariables(); // keep only the variables that appeared in both scopes foreach ($use_variables as $variable) { $variable = trim($variable, '$&'); $variables[$variable] = $static_variables[$variable]; } } return serialize(['code' => $code, 'variables' => $variables]); }
/** * get Closure info * @param Closure $c * @return array */ function closure_dump(Closure $c) { $str = 'function ('; $r = new ReflectionFunction($c); $params = array(); foreach ($r->getParameters() as $p) { $s = ''; if ($p->isArray()) { $s .= 'array '; } else { if ($p->getClass()) { $s .= $p->getClass()->name . ' '; } } if ($p->isPassedByReference()) { $s .= '&'; } $s .= '$' . $p->name; if ($p->isOptional()) { $s .= ' = ' . var_export($p->getDefaultValue(), TRUE); } $params[] = $s; } $str .= implode(', ', $params); $str .= '){' . PHP_EOL; $lines = file($r->getFileName()); for ($l = $r->getStartLine(); $l < $r->getEndLine(); $l++) { $str .= $lines[$l]; } $arr = ['file' => $r->getFileName(), 'line' => $r->getStartLine() . '-' . $r->getEndLine(), 'source' => $str]; return $arr; }
private function parseClosure(\Closure $callback) { $refl = new \ReflectionFunction($callback); // var_dump($refl->getFileName()); // var_dump($refl->getStartLine()); // var_dump($refl->getEndLine()); $body = trim(implode(array_slice(file($refl->getFileName()), $refl->getStartLine(), $refl->getEndLine() - $refl->getStartLine() - 1))); $spec = $this->createSpecification($body, $refl->getFileName(), $refl->getStartLine(), $refl->getEndLine()); return $spec; }
/** * Get the route information for a given route. * * @param \Illuminate\Routing\Route $route * @return array */ protected function getRouteInformation($route) { if (!is_a($route, 'Illuminate\\Routing\\Route')) { return array(); } $uri = head($route->methods()) . ' ' . $route->uri(); $action = $route->getAction(); $result = array('uri' => $uri ?: '-'); $result = array_merge($result, $action); if (isset($action['controller']) && strpos($action['controller'], '@') !== false) { list($controller, $method) = explode('@', $action['controller']); if (class_exists($controller) && method_exists($controller, $method)) { $reflector = new \ReflectionMethod($controller, $method); } unset($result['uses']); } elseif (isset($action['uses']) && $action['uses'] instanceof \Closure) { $reflector = new \ReflectionFunction($action['uses']); $result['uses'] = $this->formatVar($result['uses']); } if (isset($reflector)) { $filename = ltrim(str_replace(base_path(), '', $reflector->getFileName()), '/'); $result['file'] = $filename . ':' . $reflector->getStartLine() . '-' . $reflector->getEndLine(); } if ($before = $this->getBeforeFilters($route)) { $result['before'] = $before; } if ($after = $this->getAfterFilters($route)) { $result['after'] = $after; } return $result; }
public function filterResponse($response) { if (!$response->getStatusCode()) { /* keep in mind: self::$statusCode refers to the value declared in this file (500) get_called_class()::$statusCode would be the value declared in the class that extends this exception */ $className = get_called_class(); $response->status($className::$statusCode, get_class($this->originalException)); } if ($this->callback) { $closure = $this->callback->getCallable(); if (is_array($closure)) { $reflection = new \ReflectionMethod($closure[0], $closure[1]); } else { $reflection = new \ReflectionFunction($closure); } $response->header("X-Phidias-Exception-Filename", $reflection->getFilename() . ' Line: ' . $reflection->getStartLine()); } if ($message = $this->originalException->getMessage()) { $response->header("X-Phidias-Exception-Message", $message); } return $response; }
public function testConfigure() { $prevDumper = $this->getDumpHandler(); $container = new ContainerBuilder(); $container->setDefinition('var_dumper.cloner', new Definition('Symfony\\Component\\HttpKernel\\Tests\\EventListener\\MockCloner')); $container->setDefinition('mock_dumper', new Definition('Symfony\\Component\\HttpKernel\\Tests\\EventListener\\MockDumper')); ob_start(); $exception = null; $listener = new DumpListener($container, 'mock_dumper'); try { $listener->configure(); $lazyDumper = $this->getDumpHandler(); VarDumper::dump('foo'); $loadedDumper = $this->getDumpHandler(); VarDumper::dump('bar'); $this->assertSame('+foo-+bar-', ob_get_clean()); $listenerReflector = new \ReflectionClass($listener); $lazyReflector = new \ReflectionFunction($lazyDumper); $loadedReflector = new \ReflectionFunction($loadedDumper); $this->assertSame($listenerReflector->getFilename(), $lazyReflector->getFilename()); $this->assertSame($listenerReflector->getFilename(), $loadedReflector->getFilename()); $this->assertGreaterThan($lazyReflector->getStartLine(), $loadedReflector->getStartLine()); } catch (\Exception $exception) { } VarDumper::setHandler($prevDumper); if (null !== $exception) { throw $exception; } }
static function castClosure($c) { $a = array(); if (!class_exists('ReflectionFunction', false)) { return $a; } $c = new \ReflectionFunction($c); foreach ($c->getParameters() as $p) { $n = ($p->isPassedByReference() ? '&$' : '$') . $p->getName(); if ($p->isDefaultValueAvailable()) { $a[$n] = $p->getDefaultValue(); } else { $a[] = $n; } } $m = self::META_PREFIX; $a = array($m . 'returnsRef' => true, $m . 'args' => $a); if (!$c->returnsReference()) { unset($a[$m . 'returnsRef']); } $a[$m . 'use'] = array(); if (false === ($a[$m . 'file'] = $c->getFileName())) { unset($a[$m . 'file']); } else { $a[$m . 'lines'] = $c->getStartLine() . '-' . $c->getEndLine(); } if (!($c = $c->getStaticVariables())) { unset($a[$m . 'use']); } else { foreach ($c as $p => &$c) { $a[$m . 'use']['$' . $p] =& $c; } } return $a; }
function executeInSubprocess($includeStderr = false) { // Get the path to the ErrorControlChain class $classpath = SS_ClassLoader::instance()->getItemPath('ErrorControlChain'); $suppression = $this->suppression ? 'true' : 'false'; // Start building a PHP file that will execute the chain $src = '<' . "?php\nrequire_once '{$classpath}';\n\n\$chain = new ErrorControlChain();\n\n\$chain->setSuppression({$suppression});\n\n\$chain\n"; // For each step, use reflection to pull out the call, stick in the the PHP source we're building foreach ($this->steps as $step) { $func = new ReflectionFunction($step['callback']); $source = file($func->getFileName()); $start_line = $func->getStartLine() - 1; $end_line = $func->getEndLine(); $length = $end_line - $start_line; $src .= implode("", array_slice($source, $start_line, $length)) . "\n"; } // Finally add a line to execute the chain $src .= "->execute();"; // Now stick it in a temporary file & run it $codepath = TEMP_FOLDER . '/ErrorControlChainTest_' . sha1($src) . '.php'; if ($includeStderr) { $null = '&1'; } else { $null = is_writeable('/dev/null') ? '/dev/null' : 'NUL'; } file_put_contents($codepath, $src); exec("php {$codepath} 2>{$null}", $stdout, $errcode); unlink($codepath); return array(implode("\n", $stdout), $errcode); }
public function parse(&$var, Kint_Object &$o) { if (!$var instanceof Closure || !$o instanceof Kint_Object_Instance || !$this->parseChildren($o)) { return; } $o = $o->transplant(new Kint_Object_Closure()); $o->removeRepresentation('properties'); $closure = new ReflectionFunction($var); $o->filename = $closure->getFileName(); $o->startline = $closure->getStartLine(); foreach ($closure->getParameters() as $param) { $o->parameters[] = new Kint_Object_Parameter($param); } $p = new Kint_Object_Representation('Parameters'); $p->contents =& $o->parameters; $o->addRepresentation($p, 0); $statics = array(); if (method_exists($closure, 'getClosureThis') && ($v = $closure->getClosureThis())) { $statics = array('this' => $v); } if (count($statics = $statics + $closure->getStaticVariables())) { foreach ($statics as $name => &$static) { $obj = Kint_Object::blank('$' . $name); $obj->depth = $o->depth + 1; $static = $this->parser->parse($static, $obj); if ($static->value === null) { $static->access_path = null; } } $r = new Kint_Object_Representation('Uses'); $r->contents = $statics; $o->addRepresentation($r, 0); } }
public static function updateClassMethodHash($className, $methodName, $closure) { $methodName = strtolower($methodName); if (isset(self::$specialMethods[$methodName]) && self::$specialMethods[$methodName] == 1) { $methodName = "phlexmock_" . $methodName; } $closureRF = new \ReflectionFunction($closure); $paramStr = "()"; $params = []; $closureParams = $closureRF->getParameters(); if (count($closureParams) > 0) { foreach ($closureParams as $closureParam) { $params[] = '$' . $closureParam->getName(); } $paramStr = "(" . implode(",", $params) . ")"; } $sl = $closureRF->getStartLine(); $el = $closureRF->getEndLine(); $closureContainerScript = $closureRF->getFileName(); if (!isset(self::$closureContainerScriptLines[$closureContainerScript])) { self::$closureContainerScriptLines[$closureContainerScript] = explode("\n", file_get_contents($closureRF->getFileName())); } $lines = self::$closureContainerScriptLines[$closureContainerScript]; $code = '$func = function' . $paramStr . ' { ' . implode("\n", array_slice($lines, $sl, $el - $sl - 1)) . ' };'; self::$classMethodHash[$className][$methodName] = $code; }
public function onWildcardEvent() { $name = $this->events->firing(); $time = microtime(true); // Get the arguments passed to the event $params = $this->prepareParams(func_get_args()); // Find all listeners for the current event foreach ($this->events->getListeners($name) as $i => $listener) { // Check if it's an object + method name if (is_array($listener) && count($listener) > 1 && is_object($listener[0])) { list($class, $method) = $listener; // Skip this class itself if ($class instanceof static) { continue; } // Format the listener to readable format $listener = get_class($class) . '@' . $method; // Handle closures } elseif ($listener instanceof \Closure) { $reflector = new \ReflectionFunction($listener); // Skip our own listeners if ($reflector->getNamespaceName() == 'Barryvdh\\Debugbar') { continue; } // Format the closure to a readable format $filename = ltrim(str_replace(base_path(), '', $reflector->getFileName()), '/'); $listener = $reflector->getName() . ' (' . $filename . ':' . $reflector->getStartLine() . '-' . $reflector->getEndLine() . ')'; } else { // Not sure if this is possible, but to prevent edge cases $listener = $this->formatVar($listener); } $params['listeners.' . $i] = $listener; } $this->addMeasure($name, $time, $time, $params); }
public function parse(&$variable) { if (!$variable instanceof Closure) { return false; } $this->name = 'Closure'; $reflection = new ReflectionFunction($variable); $ret = array('Parameters' => array()); if ($val = $reflection->getParameters()) { foreach ($val as $parameter) { // todo http://php.net/manual/en/class.reflectionparameter.php $ret['Parameters'][] = $parameter->name; } } if ($val = $reflection->getStaticVariables()) { $ret['Uses'] = $val; } if ($val = $reflection->getClosureThis()) { $ret['Uses']['$this'] = $val; } if ($val = $reflection->getFileName()) { $this->value = Kint::shortenPath($val) . ':' . $reflection->getStartLine(); } return $ret; }
/** * 代码执行过程回溯信息 * * @static * @access public */ public static function debugBacktrace() { $skipFunc[] = 'Error->debugBacktrace'; $show = $log = ''; $debugBacktrace = debug_backtrace(); ksort($debugBacktrace); foreach ($debugBacktrace as $k => $error) { if (!isset($error['file'])) { try { if (isset($error['class'])) { $reflection = new \ReflectionMethod($error['class'], $error['function']); } else { $reflection = new \ReflectionFunction($error['function']); } $error['file'] = $reflection->getFileName(); $error['line'] = $reflection->getStartLine(); } catch (Exception $e) { continue; } } $file = str_replace(rootPath(), '', $error['file']); $func = isset($error['class']) ? $error['class'] : ''; $func .= isset($error['type']) ? $error['type'] : ''; $func .= isset($error['function']) ? $error['function'] : ''; if (in_array($func, $skipFunc)) { break; } $error['line'] = sprintf('%04d', $error['line']); $show .= '<li>[Line: ' . $error['line'] . ']' . $file . '(' . $func . ')</li>'; $log .= !empty($log) ? ' -> ' : ''; $log .= $file . ':' . $error['line']; } return array($show, $log); }
protected function export($var, $return = false) { if ($var instanceof Closure) { /* dump anonymous function in to plain code.*/ $ref = new ReflectionFunction($var); $file = new SplFileObject($ref->getFileName()); $file->seek($ref->getStartLine() - 1); $result = ''; while ($file->key() < $ref->getEndLine()) { $result .= $file->current(); $file->next(); } $begin = strpos($result, 'function'); $end = strrpos($result, '}'); $result = substr($result, $begin, $end - $begin + 1); } elseif (is_object($var)) { /* dump object with construct function. */ $result = 'new ' . get_class($var) . '(' . $this->export(get_object_vars($var), true) . ')'; } elseif (is_array($var)) { /* dump array in plain array.*/ $array = array(); foreach ($var as $k => $v) { $array[] = var_export($k, true) . ' => ' . $this->export($v, true); } $result = 'array(' . implode(', ', $array) . ')'; } else { $result = var_export($var, true); } if (!$return) { print $result; } return $result; }
public function test_populate_callback_closure() { if (version_compare(phpversion(), '5.3', '<')) { $this->markTestSkipped('PHP < 5.3 does not support closures'); return; } require_once dirname(__FILE__) . '/includes/dummy-closures.php'; $callback = self::get_callback($function); $ref = new ReflectionFunction($function); $actual = QM_Util::populate_callback($callback); $file = trim(QM_Util::standard_dir($ref->getFileName(), ''), '/'); $name = sprintf('Closure on line %1$d of %2$s', $ref->getStartLine(), $file); $this->assertEquals($function, $actual['function']); $this->assertEquals($name, $actual['name']); $this->assertEquals($ref->getFileName(), $actual['file']); $this->assertEquals($ref->getStartLine(), $actual['line']); }
static function getClosure($fn) { $source = new \ReflectionFunction($fn); $class = $source->getFileName(); $beginLine = $source->getStartLine(); $endLine = $source->getEndline(); return "{$class} {$beginLine} : {$endLine}"; }
/** * Returns the line this function's declaration starts at * * @return integer Line this function's declaration starts at */ public function getStartLine() { if ($this->reflectionSource instanceof ReflectionFunction) { return $this->reflectionSource->getStartLine(); } else { return parent::getStartLine(); } }
/** * Get start line (position) of function * * @param bool $includeDocComment * @return int */ public function getStartLine($includeDocComment = false) { if ($includeDocComment) { if ($this->getDocComment() != '') { return $this->getDocblock()->getStartLine(); } } return parent::getStartLine(); }
function dumpFuncInfo($name) { $funcInfo = new ReflectionFunction($name); var_dump($funcInfo->getName()); var_dump($funcInfo->isInternal()); var_dump($funcInfo->isUserDefined()); var_dump($funcInfo->getStartLine()); var_dump($funcInfo->getEndLine()); var_dump($funcInfo->getStaticVariables()); }
/** * Hash anything, return the unique identity. * * @param $object * @return string */ protected function hash($object) { array_walk_recursive($object, function (&$item) { if ($item instanceof \Closure) { $reflection = new \ReflectionFunction($item); $item = serialize($reflection->getClosureScopeClass()) . $reflection->getNumberOfParameters() . $reflection->getNamespaceName() . $reflection->getStartLine() . $reflection->getEndLine(); } }); return md5(serialize($object)); }
/** * Get source code of function * * @param string|\Closure $function * @return string */ public static function functionSource($function) : string { // File content $reflection = new \ReflectionFunction($function); $file = file($reflection->getFileName()); $lines = array_slice($file, $startLine = $reflection->getStartLine(), $reflection->getEndLine() - $startLine); // Last row $last = array_pop($lines); array_push($lines, rtrim(mb_substr($last, 0, mb_strrpos($last, '}')))); return static::removeIndent($lines); }
/** * Hash anything (except PDO connection stuff, for now). * * @param mixed $object * @return string */ public static function hash($object) { $object = is_array($object) ? $object : [$object]; array_walk_recursive($object, function ($item) { if ($item instanceof \Closure) { $reflection = new \ReflectionFunction($item); // Unique and fast. $item = serialize($reflection->getClosureScopeClass()) . $reflection->getNumberOfParameters() . $reflection->getNamespaceName() . $reflection->getStartLine() . $reflection->getEndLine(); } }); return md5(serialize($object)); }
/** * Checks if and where a function is defined * * @param string $name Name of the function * * @return mixed Returns the file and line of the function or false if function could not be found */ function checkFunction($name) { try { $reflection = new ReflectionFunction($name); // Utilize the ReflectionFunction class to get information about our function return $reflection->getFileName() . ':' . $reflection->getStartLine(); // Return the filename and the line where the function is defined } catch (ReflectionException $e) { return false; // Something went wrong } }
protected function execute(InputInterface $input, OutputInterface $output) { $term = $input->getArgument('search_term'); $listeners = $this->get('event.dispatcher')->getListeners(); $events = array(); foreach ($listeners as $eventName => $handlers) { foreach ($handlers as $order => $listener) { if (is_array($listener)) { list($object, $methodName) = $listener; $priority = 0; $object = get_class($object); // get the priority $objectEvents = $object::getSubscribedEvents(); $eventMethods = $objectEvents[$eventName]; if (is_array($eventMethods)) { foreach ($eventMethods as $eventMethod) { if ($eventMethod[0] == $methodName) { $priority = isset($eventMethod[1]) ? $eventMethod[1] : 0; } } } } else { $reflection = new \ReflectionFunction($listener); $file = new \Message\Cog\Filesystem\File($reflection->getFileName()); $object = $reflection->getNamespaceName() . '\\' . $file->getFilenameWithoutExtension(); $methodName = 'Closure (L:' . $reflection->getStartLine() . ' - L:' . $reflection->getEndLine() . ')'; $priority = ''; } // look for the search term if ($term && strpos(strtolower($object), strtolower($term)) === false && strpos(strtolower($methodName), strtolower($term)) === false && strpos(strtolower($eventName), strtolower($term)) === false) { continue; } $events[] = array($object, $methodName, $eventName, $priority, $order); } } // Sort events by event name, then by order of execution. uasort($events, function ($a, $b) { if ($a[2] == $b[2]) { if ($a[4] == $b[4]) { return 0; } return $a[4] < $b[4] ? -1 : 1; } return $a[2] < $b[2] ? -1 : 1; }); $output->writeln('<info>Found ' . count($events) . ' registered event listeners.</info>'); $table = $this->_getTable($output)->setHeaders(array('Class', 'Method', 'Event', 'Priority')); foreach ($events as $event) { $table->addRow(array($event[0], $event[1], $event[2], $event[3])); } $table->render($output); }
/** * Constructs annotation. * * @param callback $callback */ public function __construct($callback) { if (!is_callable($callback)) { throw new \InvalidArgumentException(sprintf('Annotation callback should be a valid callable, but %s given', gettype($callback))); } $this->closure = !is_array($callback); if (!$this->isClosure()) { $this->path = $callback[0] . '::' . $callback[1] . '()'; } else { $reflection = new \ReflectionFunction($callback); $this->path = $reflection->getFileName() . ':' . $reflection->getStartLine(); } $this->callback = $callback; }
/** * Creates a ClosureLocation and seeds it with all the data that can be gleaned from the closure's reflection * * @param \ReflectionFunction $reflection The reflection of the closure that this ClosureLocation should represent * * @return ClosureLocation */ public static function fromReflection(\ReflectionFunction $reflection) { $location = new self(); $location->directory = dirname($reflection->getFileName()); $location->file = $reflection->getFileName(); $location->function = $reflection->getName(); $location->line = $reflection->getStartLine(); // @codeCoverageIgnoreStart if (version_compare(PHP_VERSION, '5.4', '>=')) { $closureScopeClass = $reflection->getClosureScopeClass(); $location->closureScopeClass = $closureScopeClass ? $closureScopeClass->getName() : null; } // @codeCoverageIgnoreEnd return $location; }
private function getClosureCode(\Closure $closure) { $reflection = new \ReflectionFunction($closure); // Open file and seek to the first line of the closure $file = new \SplFileObject($reflection->getFileName()); $file->seek($reflection->getStartLine() - 1); // Retrieve all of the lines that contain code for the closure $code = ''; while ($file->key() < $reflection->getEndLine()) { $line = $file->current(); $line = ltrim($line); $code .= $line; $file->next(); } return $code; }
/** * Makes key from event hook. * * @param callable $hook * * @return string */ private static function make_key($hook) { if (is_array($hook)) { return implode('#', $hook); } if ($hook instanceof \Closure) { $reflection = new \ReflectionFunction($hook); return $reflection->getFileName() . '#' . $reflection->getStartLine() . '#' . $reflection->getEndLine(); } if (is_object($hook)) { /* @var $hook object */ return spl_object_hash($hook); } /* @var $hook string */ return $hook; }
/** * Get PHP code string from a closure of function as string * * @param array<string,array|string|integer> $context current compile context * @param object $closure Closure object * * @return string * * @expect 'function($a) {return;}' when input array('flags' => array('standalone' => 0)), function ($a) {return;} * @expect 'function($a) {return;}' when input array('flags' => array('standalone' => 0)), function ($a) {return;} */ protected static function closure($context, $closure) { if (is_string($closure) && preg_match('/(.+)::(.+)/', $closure, $matched)) { $ref = new \ReflectionMethod($matched[1], $matched[2]); } else { $ref = new \ReflectionFunction($closure); } $fname = $ref->getFileName(); $lines = file_get_contents($fname); $file = new \SplFileObject($fname); $file->seek($ref->getStartLine() - 2); $spos = $file->ftell(); $file->seek($ref->getEndLine() - 1); $epos = $file->ftell(); return preg_replace('/^.*?function(\\s+[^\\s\\(]+?)?\\s*\\((.+)\\}.*?\\s*$/s', 'function($2}', static::replaceSafeString($context, substr($lines, $spos, $epos - $spos))); }