Implement basic version of route matching
Make RouteConfig more readable diff --git a/app/Kernel.php b/app/Kernel.php index 4425355..a365d39 100644 --- a/app/Kernel.php +++ b/app/Kernel.php @@ -10,7 +10,7 @@ class Kernel extends BaseKernel { protected function dependencies(ContainerInterface $container): void { - $this->addRoutes($container, [ + $this->addControllers($container, [ BaseController::class, ]); } diff --git a/src/Attribute/Route.php b/src/Attribute/Route.php index 6bbd272..7129654 100644 --- a/src/Attribute/Route.php +++ b/src/Attribute/Route.php @@ -2,13 +2,15 @@ namespace Ardent\Undercurrent\Attribute; +use Ardent\Undercurrent\Http\MethodEnum; use Attribute; #[Attribute] class Route { public function __construct( - public string $path, + public string $path, + public ?MethodEnum $method = null, ) { } diff --git a/src/Http/GenericRouter.php b/src/Http/GenericRouter.php index fa1bc6a..73ce8f1 100644 --- a/src/Http/GenericRouter.php +++ b/src/Http/GenericRouter.php @@ -11,15 +11,21 @@ class GenericRouter implements RouterInterface { public function __construct( private readonly ContainerInterface $container, - private readonly RouterConfig $config, + private readonly RouterConfig $config, ) { } public function dispatch(RequestInterface $request): ResponseInterface { - $controller = $this->container->get(BaseController::class); - $method = 'helloWorld'; - return $controller->$method(); + foreach ($this->config->getRoutes() as $route) { + if ($route->getRoute()->path === $request->getUri()) { + $controller = $this->container->get($route->getController()); + $method = $route->getMethod(); + return $controller->$method(); + } + } + + throw new RouteNotFoundException($request); } } \ No newline at end of file diff --git a/src/Http/RouteConfig.php b/src/Http/RouteConfig.php new file mode 100644 index 0000000..00c2cb0 --- /dev/null +++ b/src/Http/RouteConfig.php @@ -0,0 +1,31 @@ +<?php + +namespace Ardent\Undercurrent\Http; + +use Ardent\Undercurrent\Attribute\Route; + +class RouteConfig +{ + public function __construct( + private readonly Route $route, + private readonly string $controller, + private readonly string $method + ) + { + } + + public function getRoute(): Route + { + return $this->route; + } + + public function getController(): string + { + return $this->controller; + } + + public function getMethod(): string + { + return $this->method; + } +} \ No newline at end of file diff --git a/src/Http/RouteNotFoundException.php b/src/Http/RouteNotFoundException.php new file mode 100644 index 0000000..081c625 --- /dev/null +++ b/src/Http/RouteNotFoundException.php @@ -0,0 +1,16 @@ +<?php + +namespace Ardent\Undercurrent\Http; + +use Exception; + +class RouteNotFoundException extends Exception +{ + public function __construct(RequestInterface $request) + { + parent::__construct(sprintf( + 'No controller found for uri: %s', + $request->getUri() + )); + } +} \ No newline at end of file diff --git a/src/Http/RouterConfig.php b/src/Http/RouterConfig.php index 60e5af7..eec5cde 100644 --- a/src/Http/RouterConfig.php +++ b/src/Http/RouterConfig.php @@ -2,16 +2,45 @@ namespace Ardent\Undercurrent\Http; +use Ardent\Undercurrent\Attribute\Route; +use ReflectionAttribute; +use ReflectionClass; + class RouterConfig { - public function __construct( - private readonly array $controllers = [], - ) + /** + * @var array<RouteConfig> + */ + private array $routes = []; + + public function addController(string $controller): self { + $reflectionClass = new ReflectionClass($controller); + + foreach ($reflectionClass->getMethods() as $method) { + $attributes = $method->getAttributes(Route::class, ReflectionAttribute::IS_INSTANCEOF); + + if (count($attributes) === 0) { + continue; + } + + $route = $attributes[0]->newInstance(); + + $this->routes[] = new RouteConfig( + $route, + $controller, + $method->getName(), + ); + } + + return $this; } - public function getControllers(): array + /** + * @return array<RouteConfig> + */ + public function getRoutes(): array { - return $this->controllers; + return $this->routes; } } \ No newline at end of file diff --git a/src/Kernel/BaseKernel.php b/src/Kernel/BaseKernel.php index 149aa8b..7122dcc 100644 --- a/src/Kernel/BaseKernel.php +++ b/src/Kernel/BaseKernel.php @@ -38,13 +38,16 @@ class BaseKernel echo $router->dispatch($request)->getBody(); } - protected function addRoutes(ContainerInterface $container, array $routes): void + protected function addControllers(ContainerInterface $container, array $controllers): void { - foreach ($routes as $route) { - $container->add($route); + $config = new RouterConfig(); + + foreach ($controllers as $controller) { + $container->add($controller); + $config->addController($controller); } - $container->add(RouterConfig::class, fn() => new RouterConfig($routes)); + $container->add(RouterConfig::class, fn() => $config); } protected function dependencies(ContainerInterface $container): void
This commit is contained in:
parent
96e833fb4b
commit
a854480ff1
@ -10,7 +10,7 @@ class Kernel extends BaseKernel
|
||||
{
|
||||
protected function dependencies(ContainerInterface $container): void
|
||||
{
|
||||
$this->addRoutes($container, [
|
||||
$this->addControllers($container, [
|
||||
BaseController::class,
|
||||
]);
|
||||
}
|
||||
|
@ -2,13 +2,15 @@
|
||||
|
||||
namespace Ardent\Undercurrent\Attribute;
|
||||
|
||||
use Ardent\Undercurrent\Http\MethodEnum;
|
||||
use Attribute;
|
||||
|
||||
#[Attribute]
|
||||
class Route
|
||||
{
|
||||
public function __construct(
|
||||
public string $path,
|
||||
public string $path,
|
||||
public ?MethodEnum $method = null,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
@ -11,15 +11,21 @@ class GenericRouter implements RouterInterface
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ContainerInterface $container,
|
||||
private readonly RouterConfig $config,
|
||||
private readonly RouterConfig $config,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function dispatch(RequestInterface $request): ResponseInterface
|
||||
{
|
||||
$controller = $this->container->get(BaseController::class);
|
||||
$method = 'helloWorld';
|
||||
return $controller->$method();
|
||||
foreach ($this->config->getRoutes() as $route) {
|
||||
if ($route->getRoute()->path === $request->getUri()) {
|
||||
$controller = $this->container->get($route->getController());
|
||||
$method = $route->getMethod();
|
||||
return $controller->$method();
|
||||
}
|
||||
}
|
||||
|
||||
throw new RouteNotFoundException($request);
|
||||
}
|
||||
}
|
31
src/Http/RouteConfig.php
Normal file
31
src/Http/RouteConfig.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Ardent\Undercurrent\Http;
|
||||
|
||||
use Ardent\Undercurrent\Attribute\Route;
|
||||
|
||||
class RouteConfig
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Route $route,
|
||||
private readonly string $controller,
|
||||
private readonly string $method
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function getRoute(): Route
|
||||
{
|
||||
return $this->route;
|
||||
}
|
||||
|
||||
public function getController(): string
|
||||
{
|
||||
return $this->controller;
|
||||
}
|
||||
|
||||
public function getMethod(): string
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
}
|
16
src/Http/RouteNotFoundException.php
Normal file
16
src/Http/RouteNotFoundException.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Ardent\Undercurrent\Http;
|
||||
|
||||
use Exception;
|
||||
|
||||
class RouteNotFoundException extends Exception
|
||||
{
|
||||
public function __construct(RequestInterface $request)
|
||||
{
|
||||
parent::__construct(sprintf(
|
||||
'No controller found for uri: %s',
|
||||
$request->getUri()
|
||||
));
|
||||
}
|
||||
}
|
@ -2,16 +2,45 @@
|
||||
|
||||
namespace Ardent\Undercurrent\Http;
|
||||
|
||||
use Ardent\Undercurrent\Attribute\Route;
|
||||
use ReflectionAttribute;
|
||||
use ReflectionClass;
|
||||
|
||||
class RouterConfig
|
||||
{
|
||||
public function __construct(
|
||||
private readonly array $controllers = [],
|
||||
)
|
||||
/**
|
||||
* @var array<RouteConfig>
|
||||
*/
|
||||
private array $routes = [];
|
||||
|
||||
public function addController(string $controller): self
|
||||
{
|
||||
$reflectionClass = new ReflectionClass($controller);
|
||||
|
||||
foreach ($reflectionClass->getMethods() as $method) {
|
||||
$attributes = $method->getAttributes(Route::class, ReflectionAttribute::IS_INSTANCEOF);
|
||||
|
||||
if (count($attributes) === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$route = $attributes[0]->newInstance();
|
||||
|
||||
$this->routes[] = new RouteConfig(
|
||||
$route,
|
||||
$controller,
|
||||
$method->getName(),
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getControllers(): array
|
||||
/**
|
||||
* @return array<RouteConfig>
|
||||
*/
|
||||
public function getRoutes(): array
|
||||
{
|
||||
return $this->controllers;
|
||||
return $this->routes;
|
||||
}
|
||||
}
|
@ -38,13 +38,16 @@ class BaseKernel
|
||||
echo $router->dispatch($request)->getBody();
|
||||
}
|
||||
|
||||
protected function addRoutes(ContainerInterface $container, array $routes): void
|
||||
protected function addControllers(ContainerInterface $container, array $controllers): void
|
||||
{
|
||||
foreach ($routes as $route) {
|
||||
$container->add($route);
|
||||
$config = new RouterConfig();
|
||||
|
||||
foreach ($controllers as $controller) {
|
||||
$container->add($controller);
|
||||
$config->addController($controller);
|
||||
}
|
||||
|
||||
$container->add(RouterConfig::class, fn() => new RouterConfig($routes));
|
||||
$container->add(RouterConfig::class, fn() => $config);
|
||||
}
|
||||
|
||||
protected function dependencies(ContainerInterface $container): void
|
||||
|
Loading…
Reference in New Issue
Block a user