diff --git a/src/Router.php b/src/Router.php index 04033e9..95e22b7 100644 --- a/src/Router.php +++ b/src/Router.php @@ -2,68 +2,8 @@ namespace Sharkk\Router; -class Router +interface Router { - public array $routes = []; - - public function add(string $method, string $route, callable $handler): Router - { - // Expand the route into segments and make dynamic segments into a common placeholder - $segments = array_map(function($segment) { - return str_starts_with($segment, ':') ? ':x' : $segment; - }, explode('/', trim($route, '/'))); - - // Push each segment into the routes array as a node, except if this is the root node - $node = &$this->routes; - foreach ($segments as $segment) { - // skip an empty segment, which allows us to register handlers for the root node - if ($segment === '') continue; - $node = &$node[$segment]; // build the node tree as we go - } - - // Add the handler to the last node - $node[$method] = $handler; - - return $this; - } - - // @return array{code: int, handler: callable, params: array|null } - public function lookup(string $method, string $uri): array - { - // node is a reference to our current location in the node tree - $node = $this->routes; - - // params will hold any dynamic segments we find - $params = []; - - // We'll split up the URI into segments and traverse the node tree - foreach (explode('/', trim($uri, '/')) as $segment) { - // if there is a node for this segment, move to it - if (isset($node[$segment])) { - $node = $node[$segment]; - continue; - } - - // if there is a dynamic segment, move to it and store the value - if (isset($node[':x'])) { - $params[] = $segment; - $node = $node[':x']; - continue; - } - - // if we can't find a node for this segment, return 404 - return ['code' => 404]; - } - - // if we found a handler for the method, return it and any params. if not, return a 405 - return isset($node[$method]) - ? ['code' => 200, 'handler' => $node[$method], 'params' => $params ?? null] - : ['code' => 405]; - } - - public function clear(): Router - { - $this->routes = []; - return $this; - } + public function add(string $method, string $route, callable $handler): Router; + public function lookup(string $method, string $uri): array; } diff --git a/src/SegmentRouter.php b/src/SegmentRouter.php new file mode 100644 index 0000000..1d61379 --- /dev/null +++ b/src/SegmentRouter.php @@ -0,0 +1,69 @@ +routes; + foreach ($segments as $segment) { + // skip an empty segment, which allows us to register handlers for the root node + if ($segment === '') continue; + $node = &$node[$segment]; // build the node tree as we go + } + + // Add the handler to the last node + $node[$method] = $handler; + + return $this; + } + + // @return array{code: int, handler: callable, params: array|null } + public function lookup(string $method, string $uri): array + { + // node is a reference to our current location in the node tree + $node = $this->routes; + + // params will hold any dynamic segments we find + $params = []; + + // We'll split up the URI into segments and traverse the node tree + foreach (explode('/', trim($uri, '/')) as $segment) { + // if there is a node for this segment, move to it + if (isset($node[$segment])) { + $node = $node[$segment]; + continue; + } + + // if there is a dynamic segment, move to it and store the value + if (isset($node[':x'])) { + $params[] = $segment; + $node = $node[':x']; + continue; + } + + // if we can't find a node for this segment, return 404 + return ['code' => 404]; + } + + // if we found a handler for the method, return it and any params. if not, return a 405 + return isset($node[$method]) + ? ['code' => 200, 'handler' => $node[$method], 'params' => $params ?? null] + : ['code' => 405]; + } + + public function clear(): Router + { + $this->routes = []; + return $this; + } +}