3v4l.org

run code in 300+ PHP versions simultaneously
<?php namespace Magnus; class ObjectDispatch { public function routeIterator(&$path) { while (!empty($path)) { yield end($path); array_pop($path); /* This prevents having to put back a value in the event of a * readjustment in the dispatch path. * Testing indicates that it's better to do array maninpulation than it is * to implement SplDoublyLinkedList for deque behavior. Likewise, * simply tracking the index is a bit slower and can add complexity * when dealing with reorients/redispatches. */ } } public function __invoke($context, $root) { $log = $context->logger; $path = $context->getRequestPath(); $last = ''; $parent = null; $current = $root; if ($context->appMode === 'DEBUG' && $log !== null) { $log->addDebug('Starting Object Dispatch', [ 'request' => $context->getRequestURI(), 'path' => var_export($path, true), 'root' => var_export($root, true); ]); } foreach (routeIterator($path) as $chunk) { if ($context->appMode === 'DEBUG' && $log !== null) { $log->addDebug('Beginning dispatch step.', [ 'chunk' => $chunk, 'path' => var_export($path, true), 'current' => var_export($current, true) ]); } if (!is_object($current) || class_exists($context->controllerPrefix . $current)) { if ($context->appMode === 'DEBUG' && $log !== null) { $log->addDebug('Instantiating current class', [ 'request' => $context->getRequestURI(), 'current' => $current ]); } $current = $context->controllerPrefix . $current($context); } if (is_object($current)) { $parent = $current; } if (in_array($chunk, get_class_methods($parent))) { if ($context->appMode === 'DEBUG' && $log !== null) { $log->addDebug('Found an endpoint', [ 'request' => $context->getRequestURI(), 'isEndpoint' => true, 'parent' => var_export($parent, true), 'handler' => $chunk, 'arguments' => var_export($path, true) ]); } yield array($parent, $chunk, $path, true); } elseif (in_array($chunk, get_object_vars($parent))) { if ($context->appMode === 'DEBUG' && $log !== null) { $log->addDebug('Found a property', [ 'request' => $context->getRequestURI(), 'property' => $chunk, 'parent' => var_export($parent, true) ]); } $current = $parent->chunk; } elseif (method_exists($parent, 'lookup')) { try { list($current, $consumed) = $parent->lookup($path); $chunk = implode('/', $consumed); $path = array_slice($path, 0, count($path) - count($consumed)); } catch (Exception $e) { throw new HTTPNotFound(); } } else { throw new HTTPNotFound(); } yield array(explode('/', $last), $parent, false); $last = $chunk; } if ($context->appMode === 'DEBUG' && $log !== null) { $log->addDebug('No endpoint found', [ 'request' => $context->getRequestURI(), 'current' => var_export($current), 'parent' => var_export($parent) ]); } if (!is_object($current) && class_exists($context->controllerPrefix . $current)) { $current = new $context->controllerPrefix . $current($context); } if (is_callable($current)) { yield array($current, $chunk, $path, true); } elseif (is_callable($parent)) { yield array($parent, $chunk, $path, true); } } } class Context { protected $requestURI; protected $requestPath; protected $appMode; protected $logger; protected $controllerPrefix; public function __construct(Array $config) { foreach (get_object_vars($this) as $property) { $this->$property = isset($config[$property]) ? $config[$property] : null; } } public function getRequestURI() { return $this->requestURI; } public function getRequestPath() { if (!is_array($this->requestPath)) { $this->requestPath = explode('/', str_replace('\\', '/', $this->requestURI)); } return $this->requestPath; } } class RootController { public $home = 'homeController'; public function __invoke($args = array()) { return "Root controller index"; } } $context = new Context([ 'requestURI' => '/', 'appMode' => 'development' ]); $dispatch = new ObjectDispatch(); foreach ($dispatch($context, 'rootController') as $signal) { echo var_export($signal, true) . "\n"; }

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
7.0.20.0170.05020.30
7.0.10.0030.05320.20
7.0.00.0000.04720.30
5.6.170.0270.07720.55
5.6.160.0100.05020.39
5.6.150.0100.04718.16
5.6.140.0130.06718.18
5.6.130.0130.04318.28
5.6.120.0130.08021.15
5.6.110.0070.08320.99
5.6.100.0030.04020.98
5.6.90.0170.06320.98
5.6.80.0130.07320.51
5.5.310.0270.08020.35
5.5.300.0000.08717.95
5.5.290.0130.08017.95
5.5.280.0070.08320.86
5.5.270.0200.07020.77
5.5.260.0070.08720.64
5.5.250.0030.09020.57
5.5.240.0170.07320.13

preferences:
129.32 ms | 1398 KiB | 7 Q