Compare commits

...

2 Commits

2 changed files with 82 additions and 10 deletions

View File

@ -2,8 +2,8 @@
namespace Sharkk\Router; namespace Sharkk\Router;
interface Router interface RouterInterface
{ {
public function add(string $method, string $route, callable $handler): Router; public function add(string $method, string $route, callable $handler): RouterInterface;
public function lookup(string $method, string $uri): array; public function lookup(string $method, string $uri): array;
} }

View File

@ -2,11 +2,18 @@
namespace Sharkk\Router; namespace Sharkk\Router;
class SegmentRouter implements Router class SegmentRouter implements RouterInterface
{ {
public array $routes = []; private array $routes = [];
public function add(string $method, string $route, callable $handler): Router /**
* Add a route to the route tree. The route must be a URI path, and contain dynamic segments
* using a colon prefix. (:id, :slug, etc)
*
* Example:
* `$r->add('GET', '/posts/:id', function($id) { echo "Viewing post $id"; });`
*/
public function add(string $method, string $route, callable $handler): RouterInterface
{ {
// Expand the route into segments and make dynamic segments into a common placeholder // Expand the route into segments and make dynamic segments into a common placeholder
$segments = array_map(function($segment) { $segments = array_map(function($segment) {
@ -27,7 +34,13 @@ class SegmentRouter implements Router
return $this; return $this;
} }
// @return array{code: int, handler: callable, params: array|null } /**
* Perform a lookup in the route tree for a given method and URI. Returns an array with a result code,
* a handler if found, and any dynamic parameters. Codes are 200 for success, 404 for not found, and
* 405 for method not allowed.
*
* @return array ['code', 'handler', 'params']
*/
public function lookup(string $method, string $uri): array public function lookup(string $method, string $uri): array
{ {
// node is a reference to our current location in the node tree // node is a reference to our current location in the node tree
@ -59,18 +72,77 @@ class SegmentRouter implements Router
} }
// if we can't find a node for this segment, return 404 // if we can't find a node for this segment, return 404
return ['code' => 404, 'handler' => null, 'params' => null]; return ['code' => 404, 'handler' => null, 'params' => []];
} }
// if we found a handler for the method, return it and any params. if not, return a 405 // if we found a handler for the method, return it and any params. if not, return a 405
return isset($node[$method]) return isset($node[$method])
? ['code' => 200, 'handler' => $node[$method], 'params' => $params ?? null] ? ['code' => 200, 'handler' => $node[$method], 'params' => $params ?? []]
: ['code' => 405, 'handler' => null, 'params' => null]; : ['code' => 405, 'handler' => null, 'params' => []];
} }
public function clear(): Router /**
* Clear all routes from the router.
*/
public function clear(): RouterInterface
{ {
$this->routes = []; $this->routes = [];
return $this; return $this;
} }
/**
* Dump the route tree as an array.
*/
public function dump(): array
{
return $this->routes;
}
/**
* Register a GET route.
*/
public function get(string $route, callable $handler): RouterInterface
{
return $this->add('GET', $route, $handler);
}
/**
* Register a POST route.
*/
public function post(string $route, callable $handler): RouterInterface
{
return $this->add('POST', $route, $handler);
}
/**
* Register a PUT route.
*/
public function put(string $route, callable $handler): RouterInterface
{
return $this->add('PUT', $route, $handler);
}
/**
* Register a PATCH route.
*/
public function patch(string $route, callable $handler): RouterInterface
{
return $this->add('PATCH', $route, $handler);
}
/**
* Register a DELETE route.
*/
public function delete(string $route, callable $handler): RouterInterface
{
return $this->add('DELETE', $route, $handler);
}
/**
* Register a HEAD route.
*/
public function head(string $route, callable $handler): RouterInterface
{
return $this->add('HEAD', $route, $handler);
}
} }