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