forked from PHP/Router
Add valithor's static router concept
This commit is contained in:
parent
1bff49e3ba
commit
290fc105e9
42
StaticRouter.php
Normal file
42
StaticRouter.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
class StaticRouter
|
||||
{
|
||||
public static $routes = [];
|
||||
|
||||
public static function add(string $method, string $route, callable $handler): void
|
||||
{
|
||||
$segments = array_map(function($segment) {
|
||||
return str_starts_with($segment, ':') ? ':x' : $segment;
|
||||
}, explode('/', trim($route, '/')));
|
||||
|
||||
$node = &self::$routes;
|
||||
foreach ($segments as $segment) {
|
||||
if ($segment === '') continue;
|
||||
$node = &$node[$segment];
|
||||
}
|
||||
|
||||
$node[$method] = $handler;
|
||||
}
|
||||
|
||||
public static function lookup(array $node /* = &$this->routes */, string $method, string $uri): int|array
|
||||
{
|
||||
$uriSegments = explode('/', trim($uri, '/'));
|
||||
$params = [];
|
||||
|
||||
if (isset($node[$method])) return [$node[$method], $params];
|
||||
|
||||
if (! $node2 = array_reduce($uriSegments, function ($carry, $segment) use (&$params) {
|
||||
if (isset($carry[$segment])) return $carry[$segment];
|
||||
if (isset($carry[':x'])) {
|
||||
$params[] = $segment;
|
||||
return $carry[':x'];
|
||||
}
|
||||
return null;
|
||||
}, $node)) return 404;
|
||||
|
||||
if (isset($node2[$method])) return [$node2[$method], $params];
|
||||
|
||||
return 405;
|
||||
}
|
||||
}
|
44
tests/static.php
Normal file
44
tests/static.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
require_once 'tools.php';
|
||||
require_once __DIR__ . '/../StaticRouter.php';
|
||||
|
||||
$r = new SegmentRouter();
|
||||
|
||||
// Big test
|
||||
$big = readRoutes('big.txt');
|
||||
foreach ($big as $route) {
|
||||
[$method, $path] = $route;
|
||||
$r->add($method, $path, function() {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
echoTitle("Starting big lookups");
|
||||
|
||||
$start = microtime(true);
|
||||
$reqs = 0;
|
||||
for ($i = 0; $i < 1000000; $i++) {
|
||||
$index = array_rand($big);
|
||||
[$method, $path] = $big[$index];
|
||||
$rstart = microtime(true);
|
||||
$res = StaticRouter::lookup($r->routes, $method, $path);
|
||||
if ($res === 404 || $res === 405) {
|
||||
die("404 or 405\n");
|
||||
}
|
||||
$reqs += microtime(true) - $rstart;
|
||||
}
|
||||
echo "Time: " . Color::cyan(number_format(microtime(true) - $start, 10) . " s\n");
|
||||
echo "Peak memory: " . Color::magenta(round(memory_get_peak_usage() / 1024, 1) . " kb\n");
|
||||
echo "Avg/lookup: " . Color::yellow(number_format($reqs / 1000000, 10) . " s\n");
|
||||
|
||||
function readRoutes(string $file): array
|
||||
{
|
||||
$array = [];
|
||||
$routes = file($file);
|
||||
foreach ($routes as $route) {
|
||||
[$method, $path] = explode(' ', $route);
|
||||
$path = trim($path);
|
||||
$array[] = [$method, $path];
|
||||
}
|
||||
return $array;
|
||||
}
|
Loading…
Reference in New Issue
Block a user