@ 2016-01-12T08:19:44Z <?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) {
$this->requestURI = isset($config['requestURI') ? $config['requestURI'] : '/';
$this->requestPath = isset($config['requestPath') ? $config['requestPath'] : array();
$this->appMode = isset($config['appMode') ? $config['appMode'] : 'DEVELOPMENT';
$this->logger = isset($config['logger') ? $config['logger'] : null;
$this->controllerPrefix = isset($config['controllerPrefix') ? $config['controllerPrefix'] : 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' => '/'
]);
$dispatch = new ObjectDispatch();
foreach ($dispatch($context, 'rootController') as $signal) {
echo var_export($signal, true) . "\n";
}
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
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).
Version System time (s) User time (s) Memory (MiB) 7.0.2 0.027 0.050 20.21 7.0.1 0.010 0.087 20.26 7.0.0 0.003 0.083 20.08 5.6.17 0.027 0.087 20.77 5.6.16 0.000 0.073 20.44 5.6.15 0.010 0.063 18.30 5.6.14 0.013 0.073 18.21 5.6.13 0.003 0.080 18.23 5.6.12 0.003 0.043 21.17 5.6.11 0.017 0.073 20.96 5.6.10 0.007 0.057 21.05 5.6.9 0.007 0.087 21.01 5.6.8 0.003 0.040 20.41 5.5.31 0.037 0.070 20.53 5.5.30 0.023 0.063 18.09 5.5.29 0.010 0.040 18.02 5.5.28 0.007 0.083 20.95 5.5.27 0.010 0.070 20.77 5.5.26 0.010 0.090 20.92 5.5.25 0.010 0.077 20.66 5.5.24 0.007 0.083 20.28
preferences:dark mode live preview
159.93 ms | 1398 KiB | 8 Q