diff --git a/src/Service/Router.php b/src/Service/Router.php index 2d3d03e..3c3d3e4 100644 --- a/src/Service/Router.php +++ b/src/Service/Router.php @@ -18,9 +18,15 @@ use Closure; * Currently it doesn't handle GET requests, as not needed. * But if I reuse the code in my bind Api I'll enable GET as well. */ + class Router { - private array $routes; + /* + * The easiest wy to differentiate between static and dynamic routes is using + * two arrays, no need to pollute the class Route with that information + */ + private array $staticRoutes; + private array $dynamicRoutes; public function __construct(private readonly Template $template) { @@ -47,6 +53,12 @@ class Router $regex = '/^' . str_replace(search: "/", replace: '\\/', subject: $regex) . '$/i'; $route = new Route(name: $name, route: $route, regEx: $regex, parameters: $parameters, callback: $callback); + if ($parameters) { + $this->dynamicRoutes[] = $route; + } else { + $this->staticRoutes[] = $route; + } + $this->routes[] = $route; } @@ -57,11 +69,23 @@ class Router { $requestUri = $_SERVER['REQUEST_URI']; - foreach ($this->routes as $route) { + /* + * Static routes have preference over dynamic ones, so + * /admin/user/add to add and + * /admin/user/{name} to edit is possible. + */ + foreach ($this->staticRoutes as $route) { + if (preg_match(pattern: $route->getRegex(), subject: $requestUri, matches: $matches)) { + call_user_func(callback: $route->getCallback()); + return; + } + } + + foreach ($this->dynamicRoutes as $route) { if (preg_match(pattern: $route->getRegex(), subject: $requestUri, matches: $matches)) { $parameters = []; foreach ($route->getParameters() as $id => $parameter) { - $parameters[$parameter] = $matches[$id +1]; + $parameters[$parameter] = $matches[$id + 1]; } // PHP is mad about named parameters in call_user_func // Uncaught Error: Unknown named parameter $args in …