This commit is contained in:
2025-12-30 19:28:04 +08:00
parent 5ba0f45528
commit 45ed584435
+251 -250
View File
@@ -21,300 +21,301 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate
{ {
/** /**
* @var array * @var array
*/ */
private array $_item = []; private array $_item = [];
/** /**
* @var array * @var array
*/ */
private array $dump = []; private array $dump = [];
/** /**
* @var array * @var array
*/ */
public array $groupTack = []; public array $groupTack = [];
/** /**
* @var array<string, Handler> * @var array<string, Handler>
*/ */
private array $methods = []; private array $methods = [];
/** /**
* @var array<string, HttpRequestHandler> * @var array<string, HttpRequestHandler>
*/ */
protected array $httpHandler = []; protected array $httpHandler = [];
/** /**
* @var Handler * @var Handler
*/ */
protected Handler $found; protected Handler $found;
/** /**
* @throws * @throws
*/ */
public function __construct() public function __construct()
{ {
$this->found = new Handler([NotFoundController::class, 'fail'], [], ResponseFormat::class); $this->found = new Handler([NotFoundController::class, 'fail'], [], ResponseFormat::class);
} }
/** /**
* @return Handler[] * @return Handler[]
*/ */
public function getMethods(): array public function getMethods(): array
{ {
return $this->methods; return $this->methods;
} }
/** /**
* @param string $method * @param string $method
* @param HttpRequestHandler $handler * @param HttpRequestHandler $handler
* @return void * @return void
*/ */
public function setHttpHandler(string $method, HttpRequestHandler $handler): void public function setHttpHandler(string $method, HttpRequestHandler $handler): void
{ {
$this->httpHandler[$method] = $handler; $this->httpHandler[$method] = $handler;
} }
/** /**
* @return array * @return array
*/ */
public function getDump(): array public function getDump(): array
{ {
return $this->dump; return $this->dump;
} }
/** /**
* @return Traversable * @return Traversable
*/ */
public function getIterator(): Traversable public function getIterator(): Traversable
{ {
return new \ArrayIterator($this->_item); return new \ArrayIterator($this->_item);
} }
/** /**
* @param array $method * @param array $method
* @param string $route * @param string $route
* @param string|array|Closure $closure * @param string|array|Closure $closure
*/ */
public function addRoute(array $method, string $route, string|array|Closure $closure): void public function addRoute(array $method, string $route, string|array|Closure $closure): void
{ {
try { try {
$route = $this->_splicing_routing($route); $route = $this->_splicing_routing($route);
if ($closure instanceof Closure) { if ($closure instanceof Closure) {
$handler = di(ControllerInterpreter::class)->addRouteByClosure($closure); $handler = di(ControllerInterpreter::class)->addRouteByClosure($closure);
} else { } else {
$handler = $this->resolve($closure, di(ControllerInterpreter::class)); $handler = $this->resolve($closure, di(ControllerInterpreter::class));
} }
foreach ($method as $value) { foreach ($method as $value) {
if ($value instanceof RequestMethod) { if ($value instanceof RequestMethod) {
$value = $value->getString(); $value = $value->getString();
} }
$handler->setRequestMethod($value); $handler->setRequestMethod($value);
if (is_array($closure)) { if (is_array($closure)) {
$closure[0] = is_object($closure[0]) ? get_class($closure[0]) : $closure; $closure[0] = is_object($closure[0]) ? get_class($closure[0]) : $closure;
} else if (is_string($closure)) { } else if (is_string($closure)) {
$closure = explode('@', $closure); $closure = explode('@', $closure);
} }
$this->register($route, $value, $handler); $this->register($route, $value, $handler);
} }
} catch (Throwable $throwable) { } catch (Throwable $throwable) {
error($throwable); error($throwable);
} }
} }
/** /**
* @return array * @return array
*/ */
public function dump(): array public function dump(): array
{ {
$array = []; $array = [];
foreach ($this->methods as $methodPath => $handler) { foreach ($this->methods as $methodPath => $handler) {
[$path, $method] = explode('_', $methodPath); [$path, $method] = explode('_', $methodPath);
$controller = $handler instanceof Closure ? '\Closure' : $handler->getClass() . '::' . $handler->getMethod(); $controller = $handler instanceof Closure ? '\Closure' : $handler->getClass() . '::' . $handler->getMethod();
$array[] = [ $array[] = [
'path' => $path, 'path' => $path,
'method' => $method, 'method' => $method,
'handler' => $controller 'handler' => $controller
]; ];
} }
return $array; return $array;
} }
/** /**
* @param string|array $closure * @param string|array $closure
* @param ControllerInterpreter $interpreter * @param ControllerInterpreter $interpreter
* @return Handler * @return Handler
* @throws * @throws
*/ */
private function resolve(string|array $closure, ControllerInterpreter $interpreter): Handler private function resolve(string|array $closure, ControllerInterpreter $interpreter): Handler
{ {
$container = \Kiri::getDi(); $container = \Kiri::getDi();
if (is_array($closure)) { if (is_array($closure)) {
if (is_string($closure[0])) { if (is_string($closure[0])) {
$closure[0] = $container->get($closure[0]); $closure[0] = $container->get($closure[0]);
} }
return $interpreter->addRouteByString(... $closure); return $interpreter->addRouteByString(... $closure);
} }
if (!str_contains($closure, '@')) { if (!str_contains($closure, '@')) {
$closure .= '@'; $closure .= '@';
} }
[$className, $method] = explode('@', $closure); [$className, $method] = explode('@', $closure);
$class = $container->get($this->resetName($className)); $class = $container->get($this->resetName($className));
return $interpreter->addRouteByString($class, $method); return $interpreter->addRouteByString($class, $method);
} }
/** /**
* @param string $className * @param string $className
* @return string * @return string
*/ */
private function resetName(string $className): string private function resetName(string $className): string
{ {
$namespace = array_filter(array_column($this->groupTack, 'namespace')); $namespace = array_filter(array_column($this->groupTack, 'namespace'));
if (count($namespace) < 1) { if (count($namespace) < 1) {
return $className; return $className;
} }
return implode('\\', $namespace) . '\\' . $className; return implode('\\', $namespace) . '\\' . $className;
} }
/** /**
* @param string $path * @param string $path
* @param string $method * @param string $method
* @param Handler $handler * @param Handler $handler
* @return void * @return void
* @throws * @throws
*/ */
public function register(string $path, string $method, Handler $handler): void public function register(string $path, string $method, Handler $handler): void
{ {
$this->methods[$method . '_' . $path] = $handler; $this->methods[$method . '_' . $path] = $handler;
$this->registerMiddleware($handler->getClass(), $handler->getMethod()); $this->registerMiddleware($handler->getClass(), $handler->getMethod());
} }
/** /**
* @param string $class * @param string $class
* @param string $method * @param string $method
* @return void * @return void
* @throws * @throws
*/ */
public function registerMiddleware(string $class, string $method): void public function registerMiddleware(string $class, string $method): void
{ {
$middlewares = \request()->middlewares; $middlewares = \request()->middlewares;
if (count($middlewares) > 0) { var_dump($class . '::' . $method . '('.json_encode($middlewares,JSON_UNESCAPED_UNICODE).')');
$this->appendMiddleware($middlewares, $class, $method); if (count($middlewares) > 0) {
} $this->appendMiddleware($middlewares, $class, $method);
$middlewares = array_column($this->groupTack, 'middleware'); }
if (count($middlewares) > 0) { $middlewares = array_column($this->groupTack, 'middleware');
$this->appendMiddleware($middlewares, $class, $method); if (count($middlewares) > 0) {
} $this->appendMiddleware($middlewares, $class, $method);
} }
}
/** /**
* @param array $middlewares * @param array $middlewares
* @param $class * @param $class
* @param $method * @param $method
* @return void * @return void
* @throws * @throws
*/ */
private function appendMiddleware(array $middlewares, $class, $method): void private function appendMiddleware(array $middlewares, $class, $method): void
{ {
foreach ($middlewares as $middleware) { foreach ($middlewares as $middleware) {
if (is_string($middleware)) { if (is_string($middleware)) {
$middleware = [$middleware]; $middleware = [$middleware];
} }
foreach ($middleware as $value) { foreach ($middleware as $value) {
Middleware::set($class, $method, $value); Middleware::set($class, $method, $value);
} }
} }
} }
/** /**
* @param string $path * @param string $path
* @param string $method * @param string $method
* @return HttpRequestHandler * @return HttpRequestHandler
* @throws * @throws
*/ */
public function query(string $path, string $method): HttpRequestHandler public function query(string $path, string $method): HttpRequestHandler
{ {
return $this->httpHandler[$method . '_' . $path] ?? new HttpRequestHandler([], $this->found); return $this->httpHandler[$method . '_' . $path] ?? new HttpRequestHandler([], $this->found);
} }
/** /**
* @param string $route * @param string $route
* @return string * @return string
*/ */
protected function _splicing_routing(string $route): string protected function _splicing_routing(string $route): string
{ {
$route = ltrim($route, '/'); $route = ltrim($route, '/');
$prefix = array_column($this->groupTack, 'prefix'); $prefix = array_column($this->groupTack, 'prefix');
if (empty($prefix = array_filter($prefix))) { if (empty($prefix = array_filter($prefix))) {
return '/' . $route; return '/' . $route;
} }
return '/' . implode('/', $prefix) . '/' . $route; return '/' . implode('/', $prefix) . '/' . $route;
} }
/** /**
* @param mixed $offset * @param mixed $offset
* @return bool * @return bool
*/ */
public function offsetExists(mixed $offset): bool public function offsetExists(mixed $offset): bool
{ {
// TODO: Implement offsetExists() method. // TODO: Implement offsetExists() method.
return isset($this->_item[$offset]); return isset($this->_item[$offset]);
} }
/** /**
* @param mixed $offset * @param mixed $offset
* @return Router|null * @return Router|null
*/ */
public function offsetGet(mixed $offset): ?Router public function offsetGet(mixed $offset): ?Router
{ {
if ($this->offsetExists($offset)) { if ($this->offsetExists($offset)) {
return $this->_item[$offset]; return $this->_item[$offset];
} }
return null; return null;
} }
/** /**
* @param mixed $offset * @param mixed $offset
* @param mixed $value * @param mixed $value
* @return void * @return void
*/ */
public function offsetSet(mixed $offset, mixed $value): void public function offsetSet(mixed $offset, mixed $value): void
{ {
// TODO: Implement offsetSet() method. // TODO: Implement offsetSet() method.
$this->_item[$offset] = $value; $this->_item[$offset] = $value;
} }
/** /**
* @param mixed $offset * @param mixed $offset
* @return void * @return void
*/ */
public function offsetUnset(mixed $offset): void public function offsetUnset(mixed $offset): void
{ {
unset($this->_item[$offset]); unset($this->_item[$offset]);
} }
} }