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:
@@ -28,13 +28,13 @@ class HelloWorldController
|
|||||||
return new GenericResponse('Hello World!');
|
return new GenericResponse('Hello World!');
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/routes')]
|
#[Route('/routes/{word}')]
|
||||||
public function routes(RouterConfig $config): ResponseInterface
|
public function routes(RouterConfig $config, string $word): ResponseInterface
|
||||||
{
|
{
|
||||||
$routes = implode('<br>', array_map(
|
$routes = implode('<br>', array_map(
|
||||||
fn($route) => sprintf('%s - %s->%s', $route->getRoute()->path, $route->getController(), $route->getMethod()),
|
fn($route) => sprintf('%s - %s->%s', $route->getRoute()->path, $route->getController(), $route->getMethod()),
|
||||||
$config->getRoutes()
|
$config->getRoutes()
|
||||||
));
|
)) . "<br>$word";
|
||||||
|
|
||||||
return new GenericResponse($routes);
|
return new GenericResponse($routes);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,4 +19,6 @@ interface ContainerInterface
|
|||||||
* @throws ClassNotFoundException
|
* @throws ClassNotFoundException
|
||||||
*/
|
*/
|
||||||
public function get(string $className): object;
|
public function get(string $className): object;
|
||||||
|
|
||||||
|
public function call(string $className, string $methodName, array $parameters = []): mixed;
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
namespace Ardent\Undercurrent\Container;
|
namespace Ardent\Undercurrent\Container;
|
||||||
|
|
||||||
|
use Ardent\Undercurrent\Http\RouteConfig;
|
||||||
use Exception;
|
use Exception;
|
||||||
use ReflectionClass;
|
use ReflectionClass;
|
||||||
|
use ReflectionMethod;
|
||||||
|
|
||||||
class GenericContainer implements ContainerInterface
|
class GenericContainer implements ContainerInterface
|
||||||
{
|
{
|
||||||
@@ -61,23 +63,39 @@ class GenericContainer implements ContainerInterface
|
|||||||
return $instance;
|
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
|
private function autowire(string $className): ?object
|
||||||
{
|
{
|
||||||
$reflection = new ReflectionClass($className);
|
$reflection = new ReflectionClass($className);
|
||||||
$constructor = $reflection->getConstructor();
|
$reflectionMethod = $reflection->getConstructor();
|
||||||
if (!$constructor) {
|
if (!$reflectionMethod) {
|
||||||
return new $className();
|
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 = [];
|
$params = [];
|
||||||
foreach ($constructor->getParameters() as $parameter) {
|
foreach ($reflectionMethod->getParameters() as $parameter) {
|
||||||
|
if (in_array($parameter->getName(), array_keys($exceptParams))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$type = $parameter->getType();
|
$type = $parameter->getType();
|
||||||
if (!$type) {
|
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());
|
$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
|
public function dispatch(RequestInterface $request): ResponseInterface
|
||||||
{
|
{
|
||||||
@@ -28,11 +28,11 @@ class GenericRouter implements RouterInterface
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$controller = $this->container->get($route->getController());
|
return $this->container->call(
|
||||||
$method = $route->getMethod();
|
$route->getController(),
|
||||||
// $params = $this->autowire($route) + $this->resolveParams($route->getRoute()->path, $request->getUri());
|
$route->getMethod(),
|
||||||
$params = $this->resolveParams($route->getRoute()->path, $request->getUri());
|
$params,
|
||||||
return $controller->$method(...$params);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new RouteNotFoundException($request);
|
throw new RouteNotFoundException($request);
|
||||||
@@ -40,6 +40,10 @@ class GenericRouter implements RouterInterface
|
|||||||
|
|
||||||
private function resolveParams(string $routeUri, string $requestUri): ?array
|
private function resolveParams(string $routeUri, string $requestUri): ?array
|
||||||
{
|
{
|
||||||
|
if ($routeUri === $requestUri) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
$result = preg_match_all('/{(\w+)}/', $routeUri, $tokens);
|
$result = preg_match_all('/{(\w+)}/', $routeUri, $tokens);
|
||||||
|
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
@@ -55,27 +59,11 @@ class GenericRouter implements RouterInterface
|
|||||||
) . '$/';
|
) . '$/';
|
||||||
|
|
||||||
$result = preg_match($matchingRegex, $requestUri, $matches);
|
$result = preg_match($matchingRegex, $requestUri, $matches);
|
||||||
if ($result === 0) {
|
if (!$result) {
|
||||||
return [];
|
return null;
|
||||||
}
|
}
|
||||||
$matches = array_slice($matches, 1);
|
$matches = array_slice($matches, 1);
|
||||||
|
|
||||||
return array_combine(array_map(fn($token) => trim($token, '{}'), $tokens), $matches);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user