<?php
class objectDispatch {
public function routeIterator(&$path) {
while (!empty($path)) {
yield end($path);
array_pop($path);
}
}
public function __invoke($context, $root) {
$last = '';
$parent = null;
$current = $root;
$isEndpoint = false;
$path = $context->requestPath;
foreach($this->routeIterator($path) as $chunk) {
if (!is_object($current) && class_exists($current)) {
$current = new $current();
}
if (is_object($current)) {
$parent = $current;
}
if (in_array($chunk, get_class_methods($parent))) {
yield $parent->$chunk($path);
$isEndpoint = true;
break;
} else if (array_key_exists($chunk, get_object_vars($parent))) {
$current = $parent->$chunk;
} else if (method_exists($parent, 'lookup')) {
list($current, $consumed) = $parent->lookup($path);
$chunk = implode('/', $consumed);
$truncateAt = count($consumed);
array_splice($path, $truncateAt, ($truncateAt - count($path)));
} else {
header('Http/1.0 404 Not Found');
exit();
}
$last = $chunk;
}
//No parts remaining
if (!is_object($current) && class_exists($current)) {
$current = new $current();
}
if (!$isEndpoint) {
if (is_object($current)) {
yield $current();
} else if (is_object($parent)) {
yield $parent();
}
}
}
}
class context {
public $requestPath;
public $trailing;
public function __construct($path) {
$this->trailing = false;
$requestPath = explode('/', $path);
if (end($path) == '') {
$this->trailing = (count($path) > 2);
array_pop($path);
}
$path = array_reverse($path);
if (end($path) == '') {
//Eliminate leading slashes
array_pop($path);
}
$this->requestPath = $path;
}
}
class rootController {
public $admin = 'adminController';
public function __invoke($args = []) {
return "hello from root";
}
}
class adminController {
public $user = 'usersController';
public function __invoke($args = []) {
return "hello from admin";
}
}
class usersController {
public function __invoke($args = []) {
return "hello from users";
}
public function lookup($path) {
$current = new userController($path[0]);
return [$current, [$path[0]]];
}
}
class userController {
public $id;
public function __construct($id) {
$this->id = $id;
}
public function __invoke($args = []) {
return "hello from user " . $this->id;
}
}
$context = new context('/admin/user/');
$dispatch = new objectDispatch();
foreach ($dispatch($context, 'rootController') as $dispatchMessage) {
echo $dispatchMessage;
}
preferences:
52.54 ms | 402 KiB | 5 Q