Finalize routing with injection and parameters
diff --git a/app/Controller/HelloWorldController.php b/app/Controller/HelloWorldController.php index 7f2af8b..86c5b8e 100644 --- a/app/Controller/HelloWorldController.php +++ b/app/Controller/HelloWorldController.php @@ -28,13 +28,13 @@ class HelloWorldController return new GenericResponse('Hello World!'); } - #[Route('/routes')] - public function routes(RouterConfig $config): ResponseInterface + #[Route('/routes/{word}')] + public function routes(RouterConfig $config, string $word): ResponseInterface { $routes = implode('<br>', array_map( - fn($route) => sprintf('%s - %s->%s', $route->getRoute()->path, $route->getController(), $route->getMethod()), - $config->getRoutes() - )); + fn($route) => sprintf('%s - %s->%s', $route->getRoute()->path, $route->getController(), $route->getMethod()), + $config->getRoutes() + )) . "<br>$word"; return new GenericResponse($routes); } diff --git a/src/Container/ContainerInterface.php b/src/Container/ContainerInterface.php index 7b55a94..5119eb5 100644 --- a/src/Container/ContainerInterface.php +++ b/src/Container/ContainerInterface.php @@ -19,4 +19,6 @@ interface ContainerInterface * @throws ClassNotFoundException */ public function get(string $className): object; + + public function call(string $className, string $methodName, array $parameters = []): mixed; } \ No newline at end of file diff --git a/src/Container/GenericContainer.php b/src/Container/GenericContainer.php index 8fdb26e..0e467b6 100644 --- a/src/Container/GenericContainer.php +++ b/src/Container/GenericContainer.php @@ -2,8 +2,10 @@ namespace Ardent\Undercurrent\Container; +use Ardent\Undercurrent\Http\RouteConfig; use Exception; use ReflectionClass; +use ReflectionMethod; class GenericContainer implements ContainerInterface { @@ -61,23 +63,39 @@ class GenericContainer implements ContainerInterface return $instance; } + public function call(string $className, string $methodName, array $parameters = []): mixed + { + $params = $this->methodParams($className, $methodName, $parameters) + $parameters; + return $this->get($className)->$methodName(...$params); + } + private function autowire(string $className): ?object { $reflection = new ReflectionClass($className); - $constructor = $reflection->getConstructor(); - if (!$constructor) { + $reflectionMethod = $reflection->getConstructor(); + if (!$reflectionMethod) { return new $className(); } + return new $className(...$this->methodParams($className, $reflectionMethod->getName())); + } + + private function methodParams(string $className, string $methodName, array $exceptParams = []): array + { + $reflectionMethod = new ReflectionMethod($className, $methodName); + $params = []; - foreach ($constructor->getParameters() as $parameter) { + foreach ($reflectionMethod->getParameters() as $parameter) { + if (in_array($parameter->getName(), array_keys($exceptParams))) { + continue; + } $type = $parameter->getType(); if (!$type) { - throw new Exception("Parameter {$parameter->getName()} in $className has no type"); + throw new Exception('Cannot autowire parameter without type'); } $params[] = $this->get($type->getName()); } - return new $className(...$params); + return $params; } } \ No newline at end of file diff --git a/src/Http/GenericRouter.php b/src/Http/GenericRouter.php index d5ffb95..334ecac 100644 --- a/src/Http/GenericRouter.php +++ b/src/Http/GenericRouter.php @@ -17,7 +17,7 @@ class GenericRouter implements RouterInterface } /** - * @throws RouteNotFoundException|ClassNotFoundException + * @throws RouteNotFoundException */ public function dispatch(RequestInterface $request): ResponseInterface { @@ -28,11 +28,11 @@ class GenericRouter implements RouterInterface continue; } - $controller = $this->container->get($route->getController()); - $method = $route->getMethod(); -// $params = $this->autowire($route) + $this->resolveParams($route->getRoute()->path, $request->getUri()); - $params = $this->resolveParams($route->getRoute()->path, $request->getUri()); - return $controller->$method(...$params); + return $this->container->call( + $route->getController(), + $route->getMethod(), + $params, + ); } throw new RouteNotFoundException($request); @@ -40,6 +40,10 @@ class GenericRouter implements RouterInterface private function resolveParams(string $routeUri, string $requestUri): ?array { + if ($routeUri === $requestUri) { + return []; + } + $result = preg_match_all('/{(\w+)}/', $routeUri, $tokens); if (!$result) { @@ -55,27 +59,11 @@ class GenericRouter implements RouterInterface ) . '$/'; $result = preg_match($matchingRegex, $requestUri, $matches); - if ($result === 0) { - return []; + if (!$result) { + return null; } $matches = array_slice($matches, 1); return array_combine(array_map(fn($token) => trim($token, '{}'), $tokens), $matches); } - - private function autowire(RouteConfig $route): array - { - $reflectionMethod = new ReflectionMethod($route->getController(), $route->getMethod()); - - $params = []; - foreach ($reflectionMethod->getParameters() as $parameter) { - $type = $parameter->getType(); - if (!$type) { - throw new Exception('Cannot autowire parameter without type'); - } - $params[] = $this->container->get($type->getName()); - } - - return $params; - } } \ No newline at end of file
This commit is contained in:
parent
2fd6e50b90
commit
42c590dfd6
@ -28,13 +28,13 @@ class HelloWorldController
|
||||
return new GenericResponse('Hello World!');
|
||||
}
|
||||
|
||||
#[Route('/routes')]
|
||||
public function routes(RouterConfig $config): ResponseInterface
|
||||
#[Route('/routes/{word}')]
|
||||
public function routes(RouterConfig $config, string $word): ResponseInterface
|
||||
{
|
||||
$routes = implode('<br>', array_map(
|
||||
fn($route) => sprintf('%s - %s->%s', $route->getRoute()->path, $route->getController(), $route->getMethod()),
|
||||
$config->getRoutes()
|
||||
));
|
||||
fn($route) => sprintf('%s - %s->%s', $route->getRoute()->path, $route->getController(), $route->getMethod()),
|
||||
$config->getRoutes()
|
||||
)) . "<br>$word";
|
||||
|
||||
return new GenericResponse($routes);
|
||||
}
|
||||
|
@ -19,4 +19,6 @@ interface ContainerInterface
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public function get(string $className): object;
|
||||
|
||||
public function call(string $className, string $methodName, array $parameters = []): mixed;
|
||||
}
|
@ -2,8 +2,10 @@
|
||||
|
||||
namespace Ardent\Undercurrent\Container;
|
||||
|
||||
use Ardent\Undercurrent\Http\RouteConfig;
|
||||
use Exception;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
|
||||
class GenericContainer implements ContainerInterface
|
||||
{
|
||||
@ -61,23 +63,39 @@ class GenericContainer implements ContainerInterface
|
||||
return $instance;
|
||||
}
|
||||
|
||||
public function call(string $className, string $methodName, array $parameters = []): mixed
|
||||
{
|
||||
$params = $this->methodParams($className, $methodName, $parameters) + $parameters;
|
||||
return $this->get($className)->$methodName(...$params);
|
||||
}
|
||||
|
||||
private function autowire(string $className): ?object
|
||||
{
|
||||
$reflection = new ReflectionClass($className);
|
||||
$constructor = $reflection->getConstructor();
|
||||
if (!$constructor) {
|
||||
$reflectionMethod = $reflection->getConstructor();
|
||||
if (!$reflectionMethod) {
|
||||
return new $className();
|
||||
}
|
||||
|
||||
return new $className(...$this->methodParams($className, $reflectionMethod->getName()));
|
||||
}
|
||||
|
||||
private function methodParams(string $className, string $methodName, array $exceptParams = []): array
|
||||
{
|
||||
$reflectionMethod = new ReflectionMethod($className, $methodName);
|
||||
|
||||
$params = [];
|
||||
foreach ($constructor->getParameters() as $parameter) {
|
||||
foreach ($reflectionMethod->getParameters() as $parameter) {
|
||||
if (in_array($parameter->getName(), array_keys($exceptParams))) {
|
||||
continue;
|
||||
}
|
||||
$type = $parameter->getType();
|
||||
if (!$type) {
|
||||
throw new Exception("Parameter {$parameter->getName()} in $className has no type");
|
||||
throw new Exception('Cannot autowire parameter without type');
|
||||
}
|
||||
$params[] = $this->get($type->getName());
|
||||
}
|
||||
|
||||
return new $className(...$params);
|
||||
return $params;
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ class GenericRouter implements RouterInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RouteNotFoundException|ClassNotFoundException
|
||||
* @throws RouteNotFoundException
|
||||
*/
|
||||
public function dispatch(RequestInterface $request): ResponseInterface
|
||||
{
|
||||
@ -28,11 +28,11 @@ class GenericRouter implements RouterInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
$controller = $this->container->get($route->getController());
|
||||
$method = $route->getMethod();
|
||||
// $params = $this->autowire($route) + $this->resolveParams($route->getRoute()->path, $request->getUri());
|
||||
$params = $this->resolveParams($route->getRoute()->path, $request->getUri());
|
||||
return $controller->$method(...$params);
|
||||
return $this->container->call(
|
||||
$route->getController(),
|
||||
$route->getMethod(),
|
||||
$params,
|
||||
);
|
||||
}
|
||||
|
||||
throw new RouteNotFoundException($request);
|
||||
@ -40,6 +40,10 @@ class GenericRouter implements RouterInterface
|
||||
|
||||
private function resolveParams(string $routeUri, string $requestUri): ?array
|
||||
{
|
||||
if ($routeUri === $requestUri) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$result = preg_match_all('/{(\w+)}/', $routeUri, $tokens);
|
||||
|
||||
if (!$result) {
|
||||
@ -55,27 +59,11 @@ class GenericRouter implements RouterInterface
|
||||
) . '$/';
|
||||
|
||||
$result = preg_match($matchingRegex, $requestUri, $matches);
|
||||
if ($result === 0) {
|
||||
return [];
|
||||
if (!$result) {
|
||||
return null;
|
||||
}
|
||||
$matches = array_slice($matches, 1);
|
||||
|
||||
return array_combine(array_map(fn($token) => trim($token, '{}'), $tokens), $matches);
|
||||
}
|
||||
|
||||
private function autowire(RouteConfig $route): array
|
||||
{
|
||||
$reflectionMethod = new ReflectionMethod($route->getController(), $route->getMethod());
|
||||
|
||||
$params = [];
|
||||
foreach ($reflectionMethod->getParameters() as $parameter) {
|
||||
$type = $parameter->getType();
|
||||
if (!$type) {
|
||||
throw new Exception('Cannot autowire parameter without type');
|
||||
}
|
||||
$params[] = $this->container->get($type->getName());
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user