2023-04-15 23:29:27 +08:00
|
|
|
<?php
|
|
|
|
|
|
2023-04-16 01:24:30 +08:00
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
2023-04-15 23:31:16 +08:00
|
|
|
namespace Kiri\Router;
|
2023-04-15 23:29:27 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
use Closure;
|
2023-04-15 23:31:16 +08:00
|
|
|
use Kiri\Router\Base\NotFoundController;
|
2023-04-16 01:24:30 +08:00
|
|
|
use Kiri\Router\Constrict\RequestMethod;
|
2025-12-30 20:03:40 +08:00
|
|
|
use Psr\Http\Server\MiddlewareInterface;
|
2025-12-30 20:00:50 +08:00
|
|
|
use ReflectionException;
|
2023-04-15 23:29:27 +08:00
|
|
|
use Throwable;
|
|
|
|
|
use Traversable;
|
2023-04-15 23:31:16 +08:00
|
|
|
use Kiri\Router\Base\Middleware;
|
2024-08-29 13:46:16 +08:00
|
|
|
use Kiri\Router\Format\ResponseFormat;
|
2026-04-17 16:30:52 +08:00
|
|
|
use Kiri\Router\Validator\ValidatorMiddleware;
|
2023-04-15 23:29:27 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
class RouterCollector implements \ArrayAccess, \IteratorAggregate
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
2025-12-30 19:28:04 +08:00
|
|
|
/**
|
|
|
|
|
* @var array
|
|
|
|
|
*/
|
|
|
|
|
private array $_item = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var array
|
|
|
|
|
*/
|
|
|
|
|
private array $dump = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var array
|
|
|
|
|
*/
|
|
|
|
|
public array $groupTack = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-04-17 16:30:52 +08:00
|
|
|
* @var array<string, Handler|RouteEntry>
|
2025-12-30 19:28:04 +08:00
|
|
|
*/
|
|
|
|
|
private array $methods = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var array<string, HttpRequestHandler>
|
|
|
|
|
*/
|
|
|
|
|
protected array $httpHandler = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var Handler
|
|
|
|
|
*/
|
|
|
|
|
protected Handler $found;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @throws
|
|
|
|
|
*/
|
|
|
|
|
public function __construct()
|
|
|
|
|
{
|
|
|
|
|
$this->found = new Handler([NotFoundController::class, 'fail'], [], ResponseFormat::class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-04-17 16:30:52 +08:00
|
|
|
* @return array<string, Handler|RouteEntry>
|
2025-12-30 19:28:04 +08:00
|
|
|
*/
|
|
|
|
|
public function getMethods(): array
|
|
|
|
|
{
|
|
|
|
|
return $this->methods;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2026-04-17 16:30:52 +08:00
|
|
|
public function clear(): void
|
|
|
|
|
{
|
|
|
|
|
$this->_item = [];
|
|
|
|
|
$this->dump = [];
|
|
|
|
|
$this->groupTack = [];
|
|
|
|
|
$this->methods = [];
|
|
|
|
|
$this->httpHandler = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-12-30 19:28:04 +08:00
|
|
|
/**
|
|
|
|
|
* @param string $method
|
|
|
|
|
* @param HttpRequestHandler $handler
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function setHttpHandler(string $method, HttpRequestHandler $handler): void
|
|
|
|
|
{
|
|
|
|
|
$this->httpHandler[$method] = $handler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
public function getDump(): array
|
|
|
|
|
{
|
|
|
|
|
return $this->dump;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return Traversable
|
|
|
|
|
*/
|
|
|
|
|
public function getIterator(): Traversable
|
|
|
|
|
{
|
|
|
|
|
return new \ArrayIterator($this->_item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param array $method
|
|
|
|
|
* @param string $route
|
|
|
|
|
* @param string|array|Closure $closure
|
|
|
|
|
*/
|
|
|
|
|
public function addRoute(array $method, string $route, string|array|Closure $closure): void
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
$route = $this->_splicing_routing($route);
|
|
|
|
|
if ($closure instanceof Closure) {
|
|
|
|
|
$handler = di(ControllerInterpreter::class)->addRouteByClosure($closure);
|
|
|
|
|
} else {
|
|
|
|
|
$handler = $this->resolve($closure, di(ControllerInterpreter::class));
|
|
|
|
|
}
|
|
|
|
|
foreach ($method as $value) {
|
|
|
|
|
if ($value instanceof RequestMethod) {
|
|
|
|
|
$value = $value->getString();
|
|
|
|
|
}
|
|
|
|
|
$handler->setRequestMethod($value);
|
|
|
|
|
if (is_array($closure)) {
|
|
|
|
|
$closure[0] = is_object($closure[0]) ? get_class($closure[0]) : $closure;
|
|
|
|
|
} else if (is_string($closure)) {
|
|
|
|
|
$closure = explode('@', $closure);
|
|
|
|
|
}
|
|
|
|
|
$this->register($route, $value, $handler);
|
|
|
|
|
}
|
|
|
|
|
} catch (Throwable $throwable) {
|
2025-12-31 00:19:29 +08:00
|
|
|
\Kiri::getLogger()->json_log($throwable);
|
2025-12-30 19:28:04 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
public function dump(): array
|
|
|
|
|
{
|
|
|
|
|
$array = [];
|
|
|
|
|
foreach ($this->methods as $methodPath => $handler) {
|
|
|
|
|
[$path, $method] = explode('_', $methodPath);
|
|
|
|
|
|
|
|
|
|
$controller = $handler instanceof Closure ? '\Closure' : $handler->getClass() . '::' . $handler->getMethod();
|
|
|
|
|
$array[] = [
|
|
|
|
|
'path' => $path,
|
|
|
|
|
'method' => $method,
|
|
|
|
|
'handler' => $controller
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
return $array;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string|array $closure
|
|
|
|
|
* @param ControllerInterpreter $interpreter
|
|
|
|
|
* @return Handler
|
|
|
|
|
* @throws
|
|
|
|
|
*/
|
|
|
|
|
private function resolve(string|array $closure, ControllerInterpreter $interpreter): Handler
|
|
|
|
|
{
|
|
|
|
|
$container = \Kiri::getDi();
|
|
|
|
|
if (is_array($closure)) {
|
|
|
|
|
if (is_string($closure[0])) {
|
|
|
|
|
$closure[0] = $container->get($closure[0]);
|
|
|
|
|
}
|
2026-04-17 16:30:52 +08:00
|
|
|
$handler = $interpreter->addRouteByString(... $closure);
|
|
|
|
|
$sourceFile = Router::getCurrentSourceFile();
|
|
|
|
|
if ($sourceFile !== null) {
|
|
|
|
|
$handler->setSourceFile($sourceFile);
|
|
|
|
|
$handler->setSourceKind('route_file');
|
|
|
|
|
}
|
|
|
|
|
return $handler;
|
2025-12-30 19:28:04 +08:00
|
|
|
}
|
|
|
|
|
if (!str_contains($closure, '@')) {
|
|
|
|
|
$closure .= '@';
|
|
|
|
|
}
|
|
|
|
|
[$className, $method] = explode('@', $closure);
|
|
|
|
|
$class = $container->get($this->resetName($className));
|
2026-04-17 16:30:52 +08:00
|
|
|
$handler = $interpreter->addRouteByString($class, $method);
|
|
|
|
|
$sourceFile = Router::getCurrentSourceFile();
|
|
|
|
|
if ($sourceFile !== null) {
|
|
|
|
|
$handler->setSourceFile($sourceFile);
|
|
|
|
|
$handler->setSourceKind('route_file');
|
|
|
|
|
}
|
|
|
|
|
return $handler;
|
2025-12-30 19:28:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $className
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private function resetName(string $className): string
|
|
|
|
|
{
|
|
|
|
|
$namespace = array_filter(array_column($this->groupTack, 'namespace'));
|
|
|
|
|
if (count($namespace) < 1) {
|
|
|
|
|
return $className;
|
|
|
|
|
}
|
|
|
|
|
return implode('\\', $namespace) . '\\' . $className;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $path
|
|
|
|
|
* @param string $method
|
|
|
|
|
* @param Handler $handler
|
|
|
|
|
* @return void
|
|
|
|
|
* @throws
|
|
|
|
|
*/
|
|
|
|
|
public function register(string $path, string $method, Handler $handler): void
|
|
|
|
|
{
|
2026-04-17 16:30:52 +08:00
|
|
|
if ($handler->getSourceFile() === null && $handler->getClass() !== null) {
|
|
|
|
|
$reflect = \Kiri::getDi()->getReflectionClass($handler->getClass());
|
|
|
|
|
$handler->setSourceFile($this->normalizePath((string)$reflect->getFileName()));
|
|
|
|
|
$handler->setSourceKind('attribute');
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-30 19:28:04 +08:00
|
|
|
$this->methods[$method . '_' . $path] = $handler;
|
2025-12-30 20:21:44 +08:00
|
|
|
$handler->setMiddlewares($this->registerMiddleware($handler->getClass(), $handler->getMethod()));
|
2025-12-30 19:28:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2026-04-17 16:30:52 +08:00
|
|
|
public function exportArtifact(): array
|
|
|
|
|
{
|
|
|
|
|
$entries = [];
|
|
|
|
|
$hasClosureRoutes = false;
|
|
|
|
|
|
|
|
|
|
foreach ($this->methods as $methodPath => $handler) {
|
|
|
|
|
if ($handler instanceof Handler && $handler->isClosure()) {
|
|
|
|
|
$hasClosureRoutes = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[$requestMethod, $path] = explode('_', $methodPath, 2);
|
|
|
|
|
$class = $handler instanceof Handler ? $handler->getClass() : $handler->class;
|
|
|
|
|
$method = $handler instanceof Handler ? $handler->getMethod() : $handler->method;
|
|
|
|
|
$middlewares = $handler instanceof Handler ? $handler->getMiddlewares() : $handler->middlewares;
|
|
|
|
|
$sourceFile = $handler instanceof Handler ? $handler->getSourceFile() : $handler->sourceFile;
|
|
|
|
|
$sourceKind = $handler instanceof Handler ? $handler->getSourceKind() : $handler->sourceKind;
|
|
|
|
|
|
|
|
|
|
$entries[] = [
|
|
|
|
|
'request_method' => $requestMethod,
|
|
|
|
|
'path' => $path,
|
|
|
|
|
'class' => $class,
|
|
|
|
|
'method' => $method,
|
|
|
|
|
'middlewares' => $middlewares,
|
|
|
|
|
'source_file' => $sourceFile,
|
|
|
|
|
'source_kind' => $sourceKind,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
'has_closure_routes' => $hasClosureRoutes,
|
|
|
|
|
'entries' => $entries,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function importArtifact(array $artifact, array $excludeSourceFiles = []): bool
|
|
|
|
|
{
|
|
|
|
|
if (($artifact['has_closure_routes'] ?? false) === true) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$entries = $artifact['entries'] ?? null;
|
|
|
|
|
if (!is_array($entries)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$exclude = array_fill_keys(array_map([$this, 'normalizePath'], $excludeSourceFiles), true);
|
|
|
|
|
foreach ($entries as $entry) {
|
|
|
|
|
if (!is_array($entry)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$sourceFile = $entry['source_file'] ?? null;
|
|
|
|
|
if (is_string($sourceFile) && isset($exclude[$this->normalizePath($sourceFile)])) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$class = $entry['class'] ?? null;
|
|
|
|
|
$method = $entry['method'] ?? null;
|
|
|
|
|
$requestMethod = $entry['request_method'] ?? null;
|
|
|
|
|
$path = $entry['path'] ?? null;
|
|
|
|
|
|
|
|
|
|
if (!is_string($class) || !is_string($method) || !is_string($requestMethod) || !is_string($path)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->methods[$requestMethod . '_' . $path] = new RouteEntry(
|
|
|
|
|
requestMethod: $requestMethod,
|
|
|
|
|
path: $path,
|
|
|
|
|
class: $class,
|
|
|
|
|
method: $method,
|
|
|
|
|
middlewares: is_array($entry['middlewares'] ?? null) ? $entry['middlewares'] : [],
|
|
|
|
|
sourceFile: is_string($sourceFile) ? $this->normalizePath($sourceFile) : null,
|
|
|
|
|
sourceKind: is_string($entry['source_kind'] ?? null) ? $entry['source_kind'] : 'attribute',
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-12-30 19:28:04 +08:00
|
|
|
/**
|
|
|
|
|
* @param string $class
|
|
|
|
|
* @param string $method
|
2025-12-30 20:00:50 +08:00
|
|
|
* @return array
|
|
|
|
|
* @throws ReflectionException
|
2025-12-30 19:28:04 +08:00
|
|
|
*/
|
2025-12-30 20:00:50 +08:00
|
|
|
public function registerMiddleware(string $class, string $method): array
|
2025-12-30 19:28:04 +08:00
|
|
|
{
|
2025-12-30 20:00:50 +08:00
|
|
|
$response = [];
|
2025-12-30 21:15:25 +08:00
|
|
|
$middlewares = \config('servers.request.middlewares', []);
|
|
|
|
|
if (is_array($middlewares) && count($middlewares) > 0) {
|
|
|
|
|
$response = $this->appendMiddleware($response, $middlewares);
|
|
|
|
|
}
|
2025-12-30 19:28:04 +08:00
|
|
|
$middlewares = array_column($this->groupTack, 'middleware');
|
2025-12-30 20:00:50 +08:00
|
|
|
$response = $this->appendMiddleware($response, $middlewares);
|
|
|
|
|
|
2025-12-30 21:15:25 +08:00
|
|
|
return $this->read_method_middleware($response, $class, $method);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param array $response
|
|
|
|
|
* @param string $class
|
|
|
|
|
* @param string $method
|
|
|
|
|
* @return array
|
|
|
|
|
* @throws ReflectionException
|
|
|
|
|
*/
|
|
|
|
|
private function read_method_middleware(array $response, string $class, string $method): array
|
|
|
|
|
{
|
2025-12-30 20:21:44 +08:00
|
|
|
$reflect = \Kiri::getDi()->getReflectionClass($class);
|
2025-12-30 20:00:50 +08:00
|
|
|
$attributes = $reflect->getMethod($method)->getAttributes(Annotate\Middleware::class);
|
|
|
|
|
|
|
|
|
|
foreach ($attributes as $attribute) {
|
2025-12-30 20:03:40 +08:00
|
|
|
/** @var Annotate\Middleware $instance */
|
|
|
|
|
$instance = $attribute->newInstance();
|
|
|
|
|
|
|
|
|
|
$data = $instance->middleware;
|
|
|
|
|
if (is_string($data)) {
|
|
|
|
|
$data = [$data];
|
2025-12-30 20:21:44 +08:00
|
|
|
}
|
2025-12-30 20:03:40 +08:00
|
|
|
|
2025-12-30 20:21:44 +08:00
|
|
|
foreach ($data as $middleware) {
|
2025-12-30 20:03:40 +08:00
|
|
|
if (!in_array($middleware, $response)) {
|
|
|
|
|
$response[] = $middleware;
|
|
|
|
|
}
|
2025-12-30 20:00:50 +08:00
|
|
|
}
|
2025-12-30 19:28:04 +08:00
|
|
|
}
|
2025-12-30 20:21:44 +08:00
|
|
|
return $response;
|
2025-12-30 19:28:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2025-12-30 20:00:50 +08:00
|
|
|
* @param array $response
|
2025-12-30 19:28:04 +08:00
|
|
|
* @param array $middlewares
|
2025-12-30 20:00:50 +08:00
|
|
|
* @return array
|
2025-12-30 19:28:04 +08:00
|
|
|
*/
|
2025-12-30 20:00:50 +08:00
|
|
|
private function appendMiddleware(array $response, array $middlewares): array
|
2025-12-30 19:28:04 +08:00
|
|
|
{
|
|
|
|
|
foreach ($middlewares as $middleware) {
|
|
|
|
|
if (is_string($middleware)) {
|
|
|
|
|
$middleware = [$middleware];
|
|
|
|
|
}
|
|
|
|
|
foreach ($middleware as $value) {
|
2025-12-30 20:00:50 +08:00
|
|
|
if (!in_array($value, $response)) {
|
|
|
|
|
$response[] = $value;
|
|
|
|
|
}
|
2025-12-30 19:28:04 +08:00
|
|
|
}
|
|
|
|
|
}
|
2025-12-30 20:00:50 +08:00
|
|
|
return $response;
|
2025-12-30 19:28:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $path
|
|
|
|
|
* @param string $method
|
|
|
|
|
* @return HttpRequestHandler
|
|
|
|
|
* @throws
|
|
|
|
|
*/
|
|
|
|
|
public function query(string $path, string $method): HttpRequestHandler
|
|
|
|
|
{
|
2026-04-17 16:30:52 +08:00
|
|
|
$key = $method . '_' . $path;
|
|
|
|
|
if (!isset($this->httpHandler[$key]) && isset($this->methods[$key])) {
|
|
|
|
|
$this->httpHandler[$key] = $this->compileHandler($this->methods[$key]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->httpHandler[$key] ?? $this->not_found_handler();
|
2025-12-30 21:37:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return HttpRequestHandler
|
|
|
|
|
*/
|
|
|
|
|
protected function not_found_handler(): HttpRequestHandler
|
|
|
|
|
{
|
|
|
|
|
$middlewares = \config('servers.request.middlewares', []);
|
|
|
|
|
if (!is_array($middlewares) || count($middlewares) < 1) {
|
|
|
|
|
return new HttpRequestHandler($middlewares, $this->found);
|
|
|
|
|
}
|
|
|
|
|
for ($index = 0; $index < count($middlewares); $index++) {
|
|
|
|
|
$middlewares[$index] = \Kiri::getDi()->get($middlewares[$index]);
|
|
|
|
|
}
|
|
|
|
|
return new HttpRequestHandler($middlewares, $this->found);
|
2025-12-30 19:28:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2026-04-17 16:30:52 +08:00
|
|
|
public function warmHttpHandlers(): void
|
|
|
|
|
{
|
|
|
|
|
foreach ($this->methods as $name => $method) {
|
|
|
|
|
$this->httpHandler[$name] = $this->compileHandler($method);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-12-30 19:28:04 +08:00
|
|
|
/**
|
|
|
|
|
* @param string $route
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
protected function _splicing_routing(string $route): string
|
|
|
|
|
{
|
|
|
|
|
$route = ltrim($route, '/');
|
|
|
|
|
$prefix = array_column($this->groupTack, 'prefix');
|
|
|
|
|
if (empty($prefix = array_filter($prefix))) {
|
|
|
|
|
return '/' . $route;
|
|
|
|
|
}
|
|
|
|
|
return '/' . implode('/', $prefix) . '/' . $route;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2026-04-17 16:30:52 +08:00
|
|
|
private function normalizePath(string $path): string
|
|
|
|
|
{
|
|
|
|
|
$resolved = realpath($path) ?: $path;
|
|
|
|
|
return str_replace('\\', '/', $resolved);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function compileHandler(Handler|RouteEntry $method): HttpRequestHandler
|
|
|
|
|
{
|
|
|
|
|
if ($method instanceof RouteEntry) {
|
|
|
|
|
$controller = \Kiri::getDi()->get($method->class);
|
|
|
|
|
$handler = di(ControllerInterpreter::class)->addRouteByString($controller, $method->method);
|
|
|
|
|
$handler->setRequestMethod($method->requestMethod);
|
|
|
|
|
$handler->setMiddlewares($method->middlewares);
|
|
|
|
|
$handler->setSourceFile($method->sourceFile);
|
|
|
|
|
$handler->setSourceKind($method->sourceKind);
|
|
|
|
|
$method = $handler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$middlewares = $method->getMiddlewares();
|
|
|
|
|
foreach ($middlewares as $key => $middleware) {
|
|
|
|
|
$middlewares[$key] = di($middleware);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$requestHandler = new HttpRequestHandler($middlewares, $method);
|
|
|
|
|
$validator = Middleware::getValidator($method->getClass(), $method->getMethod());
|
|
|
|
|
if ($validator !== null) {
|
|
|
|
|
$requestHandler->withValidatorMiddleware(new ValidatorMiddleware(di(\Psr\Http\Message\ResponseInterface::class), $method->getClass(), $method->getMethod()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $requestHandler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-12-30 19:28:04 +08:00
|
|
|
/**
|
|
|
|
|
* @param mixed $offset
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
public function offsetExists(mixed $offset): bool
|
|
|
|
|
{
|
|
|
|
|
// TODO: Implement offsetExists() method.
|
|
|
|
|
return isset($this->_item[$offset]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param mixed $offset
|
|
|
|
|
* @return Router|null
|
|
|
|
|
*/
|
|
|
|
|
public function offsetGet(mixed $offset): ?Router
|
|
|
|
|
{
|
|
|
|
|
if ($this->offsetExists($offset)) {
|
|
|
|
|
return $this->_item[$offset];
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param mixed $offset
|
|
|
|
|
* @param mixed $value
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function offsetSet(mixed $offset, mixed $value): void
|
|
|
|
|
{
|
|
|
|
|
// TODO: Implement offsetSet() method.
|
|
|
|
|
$this->_item[$offset] = $value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param mixed $offset
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function offsetUnset(mixed $offset): void
|
|
|
|
|
{
|
|
|
|
|
unset($this->_item[$offset]);
|
|
|
|
|
}
|
2023-04-15 23:29:27 +08:00
|
|
|
}
|