diff --git a/Annotation/Annotation.php b/Annotation/Annotation.php index 3d175763..8122ce86 100644 --- a/Annotation/Annotation.php +++ b/Annotation/Annotation.php @@ -192,14 +192,9 @@ class Annotation extends Component * @param string|array $outPath * @throws Exception */ - public function runtime(string $dir, string|array $outPath = '') + public function runtime(string $dir) { - if (empty($outPath)) { - $outPath = []; - } else if (is_string($outPath)) { - $outPath = [$outPath]; - } - $this->_loader->loadByDirectory($dir, $outPath); + return $this->_loader->loadByDirectory($dir); } diff --git a/Annotation/Loader.php b/Annotation/Loader.php index 2770c5c7..81153c48 100644 --- a/Annotation/Loader.php +++ b/Annotation/Loader.php @@ -38,13 +38,6 @@ class Loader extends BaseObject private static array $_methods = []; - /** - * @return array - */ - public function getDirectory(): array - { - return static::$_directory; - } /** * @param $path @@ -56,16 +49,6 @@ class Loader extends BaseObject $this->_scanDir(new DirectoryIterator($path), $namespace); } - - /** - * @return array - */ - public function getClasses(): array - { - return static::$_classes; - } - - /** * @param string $class * @param string $property @@ -121,16 +104,6 @@ class Loader extends BaseObject } - /** - * @param string $class - * @return array - */ - public function getTarget(string $class): array - { - return static::$_classes[$class] ?? []; - } - - /** * @param DirectoryIterator $paths * @param $namespace @@ -173,16 +146,7 @@ class Loader extends BaseObject } $this->appendFileToDirectory($path->getRealPath(), $replace->getName()); - $_array['handler'] = $replace->newInstance(); - $_array['target'] = []; - $_array['methods'] = []; - $_array['property'] = []; - - $_array = $this->_targets($replace, $_array); - $_array = $this->_methods($replace, $_array); - $_array = $this->_properties($replace, $_array); - - static::$_classes[$replace->getName()] = $_array; + static::$_classes[] = $replace->getName(); } catch (Throwable $throwable) { $this->addError($throwable, 'throwable'); } @@ -202,75 +166,6 @@ class Loader extends BaseObject } - /** - * @param ReflectionClass $replace - * @param array $_array - * @return array - */ - private function _targets(ReflectionClass $replace, array $_array): array - { - foreach ($replace->getAttributes() as $attribute) { - if ($attribute->getName() == Attribute::class) { - continue; - } - if ($attribute->getName() == Target::class) { - continue; - } - $_array['target'][] = $attribute->newInstance(); - } - return $_array; - } - - - /** - * @param ReflectionClass $replace - * @param array $_array - * @return array - */ - private function _methods(ReflectionClass $replace, array $_array): array - { - $methods = $replace->getMethods(ReflectionMethod::IS_PUBLIC); - foreach ($methods as $method) { - $_method = []; - foreach ($method->getAttributes() as $attribute) { - if (!class_exists($attribute->getName())) { - continue; - } - $_method[] = $attribute->newInstance(); - } - if (!empty($_method)) { - static::$_methods[$replace->getName()][$method->getName()] = $_method; - } - } - return $_array; - } - - - /** - * @param ReflectionClass $replace - * @param array $_array - * @return array - */ - private function _properties(ReflectionClass $replace, array $_array): array - { - $methods = $replace->getProperties(); - foreach ($methods as $method) { - $_property = []; - if ($method->isStatic()) continue; - foreach ($method->getAttributes() as $attribute) { - if (!class_exists($attribute->getName())) { - continue; - } - $_property[] = $attribute->newInstance(); - } - if (!empty($_property)) { - static::$_property[$replace->getName()][$method->getName()] = $_property; - } - } - return $_array; - } - - /** * @param string $path * @param string|array $outPath @@ -280,15 +175,22 @@ class Loader extends BaseObject { try { $path = '/' . trim($path, '/'); + + $paths = []; foreach (static::$_directory as $key => $_path) { $key = '/' . trim($key, '/'); if (!str_starts_with($key, $path) || in_array($key, $outPath)) { continue; } - $this->execute($_path); + + foreach ($_path as $item) { + $paths[] = $item; + } } + return $paths; } catch (Throwable $exception) { $this->addError($exception, 'throwable'); + return []; } } @@ -326,38 +228,4 @@ class Loader extends BaseObject } - /** - * @param array $classes - * @throws Exception - */ - private function execute(array $classes) - { - if (empty($classes)) { - return; - } - foreach ($classes as $className) { - if (!isset(static::$_methods[$className])) { - continue; - } - foreach (static::$_methods[$className] as $name => $attribute) { - $this->methods($attribute, $className, $name); - } - } - } - - - /** - * @param $attribute - * @param $annotation - * @param $className - * @param $name - */ - private function methods($attribute, $className, $name) - { - $handler = static::$_classes[$className]['handler']; - foreach ($attribute as $value) { - $value->execute($handler, $name); - } - } - } diff --git a/Annotation/Model/Get.php b/Annotation/Model/Get.php index e10f4257..77592126 100644 --- a/Annotation/Model/Get.php +++ b/Annotation/Model/Get.php @@ -4,9 +4,7 @@ namespace Annotation\Model; -use Annotation\Annotation; use Attribute; -use Database\ActiveRecord; use Exception; use Snowflake\Snowflake; diff --git a/Annotation/Route/Interceptor.php b/Annotation/Route/Interceptor.php deleted file mode 100644 index c7974696..00000000 --- a/Annotation/Route/Interceptor.php +++ /dev/null @@ -1,52 +0,0 @@ -interceptor)) { - $this->interceptor = [$this->interceptor]; - } - - foreach ($this->interceptor as $key => $value) { - $sn = Snowflake::createObject($value); - - if (!($sn instanceof \HttpServer\IInterface\Interceptor)) { - continue; - } - - $this->interceptor[$key] = [$sn, 'Interceptor']; - } - } - - - /** - * @param mixed $class - * @param mixed|null $method - * @return Interceptor - */ - public function execute(mixed $class, mixed $method = null): static - { - return $this; - } - -} diff --git a/Annotation/Route/Limits.php b/Annotation/Route/Limits.php deleted file mode 100644 index f9f1ac94..00000000 --- a/Annotation/Route/Limits.php +++ /dev/null @@ -1,52 +0,0 @@ -limits)) { - $this->limits = [$this->limits]; - } - - foreach ($this->limits as $key => $value) { - $sn = Snowflake::createObject($value); - - if (!($sn instanceof \HttpServer\IInterface\Limits)) { - continue; - } - - $this->limits[$key] = [$sn, 'next']; - } - } - - - /** - * @param mixed $class - * @param mixed|null $method - * @return Limits - */ - public function execute(mixed $class, mixed $method = null): static - { - return $this; - } - - -} diff --git a/Annotation/Route/Middleware.php b/Annotation/Route/Middleware.php index 0395e321..87113ad4 100644 --- a/Annotation/Route/Middleware.php +++ b/Annotation/Route/Middleware.php @@ -5,6 +5,7 @@ namespace Annotation\Route; use Annotation\Attribute; +use HttpServer\Route\Middlewares; use Snowflake\Snowflake; use HttpServer\IInterface\Middleware as IMiddleware; @@ -16,38 +17,40 @@ use HttpServer\IInterface\Middleware as IMiddleware; { - /** - * Interceptor constructor. - * @param string|array $middleware - * @throws - */ - public function __construct(public string|array $middleware) - { - if (is_string($this->middleware)) { - $this->middleware = [$this->middleware]; - } + /** + * Interceptor constructor. + * @param string|array $middleware + * @throws + */ + public function __construct(public string|array $middleware) + { + if (is_string($this->middleware)) { + $this->middleware = [$this->middleware]; + } - $array = []; - foreach ($this->middleware as $key => $value) { - $sn = Snowflake::createObject($value); - if (!($sn instanceof IMiddleware)) { - continue; - } - $array[] = [$sn, 'onHandler']; - } - $this->middleware = $array; - } + $array = []; + foreach ($this->middleware as $value) { + $sn = Snowflake::createObject($value); + if (!($sn instanceof IMiddleware)) { + continue; + } + $array[] = [$sn, 'onHandler']; + } + $this->middleware = $array; + } - /** - * @param mixed $class - * @param mixed|null $method - * @return Middleware - */ + /** + * @param mixed $class + * @param mixed|null $method + * @return Middleware + */ public function execute(mixed $class, mixed $method = null): static - { - return $this; - } + { + $middleware = Snowflake::getDi()->get(Middlewares::class); + $middleware->addMiddlewares($class, $method, $this->middleware); + return $this; + } } diff --git a/Annotation/Route/Route.php b/Annotation/Route/Route.php index 4c48bdc9..be7c2fa3 100644 --- a/Annotation/Route/Route.php +++ b/Annotation/Route/Route.php @@ -13,36 +13,43 @@ use Snowflake\Snowflake; #[\Attribute(\Attribute::TARGET_METHOD)] class Route extends Attribute { - /** - * Route constructor. - * @param string $uri - * @param string $method - * @param string $version - */ - public function __construct( - public string $uri, - public string $method, - public string $version = 'v.1.0' - ) - { - } + /** + * Route constructor. + * @param string $uri + * @param string $method + * @param string $version + */ + public function __construct( + public string $uri, + public string $method, + public string $version = 'v.1.0' + ) + { + } - /** - * @param mixed $class - * @param mixed|null $method - * @return Router - * @throws Exception - */ + /** + * @param mixed $class + * @param mixed|null $method + * @return Router + * @throws Exception + */ public function execute(mixed $class, mixed $method = null): Router - { - // TODO: Implement setHandler() method. - $router = Snowflake::app()->getRouter(); - - $router->addRoute($this->uri, [$class, $method], $this->method); - - return $router; - } + { + // TODO: Implement setHandler() method. + $router = Snowflake::app()->getRouter(); + $node = $router->addRoute($this->uri, [$class, $method], $this->method); + if ($node !== null) { + $attribute = Snowflake::getDi()->getMethodAttribute($class::class, $method); + foreach ($attribute as $item) { + if ($item instanceof Route) { + continue; + } + $item->execute($class, $method); + } + } + return $router; + } } diff --git a/HttpServer/Route/Middlewares.php b/HttpServer/Route/Middlewares.php new file mode 100644 index 00000000..ceb4bdd1 --- /dev/null +++ b/HttpServer/Route/Middlewares.php @@ -0,0 +1,69 @@ +onHandler($passable, $stack); + } + return call_user_func($pipe, $passable, $stack); + }; + }, $caller); + } + +} diff --git a/HttpServer/Route/Node.php b/HttpServer/Route/Node.php index 56f572fa..75a3daee 100644 --- a/HttpServer/Route/Node.php +++ b/HttpServer/Route/Node.php @@ -5,15 +5,10 @@ declare(strict_types=1); namespace HttpServer\Route; -use Annotation\Route\After; -use Annotation\Route\Interceptor; -use Annotation\Route\Limits; -use Annotation\Route\Middleware; use Annotation\Route\RpcProducer; use Closure; use Exception; use HttpServer\Abstracts\HttpService; -use HttpServer\Controller; use HttpServer\Http\Context; use HttpServer\Http\Request; use JetBrains\PhpStorm\Pure; @@ -22,7 +17,6 @@ use Snowflake\Aop; use Snowflake\Core\Json; use Snowflake\Exception\NotFindClassException; use Snowflake\Snowflake; -use Throwable; /** * Class Node @@ -31,524 +25,288 @@ use Throwable; class Node extends HttpService { - public string $path = ''; - public int $index = 0; - public string $method = ''; - - /** @var Node[] $childes */ - public array $childes = []; - - public array $group = []; - - private string $_error = ''; - - private string $_dataType = ''; - - /** @var ?Closure|?array */ - public Closure|array|null $handler; - public string $htmlSuffix = '.html'; - public bool $enableHtmlSuffix = false; - public array $namespace = []; - public array $middleware = []; - - /** @var array|Closure */ - public Closure|array $callback = []; - - private string $_alias = ''; - - private array $_interceptors = []; - private array $_after = []; - private array $_limits = []; - - - /** - * @param string $dataType - */ - public function setDataType(string $dataType) - { - $this->_dataType = $dataType; - } - - - /** - * @param string $data - * @return mixed - */ - public function unpack(string $data): mixed - { - if ($this->_dataType == RpcProducer::PROTOCOL_JSON) { - return json_decode($data, true); - } - if ($this->_dataType == RpcProducer::PROTOCOL_SERIALIZE) { - return unserialize($data); - } - return $data; - } - - - /** - * @param $handler - * @return Node - * @throws - */ - public function bindHandler($handler): static - { - if (is_string($handler) && str_contains($handler, '@')) { - list($controller, $action) = explode('@', $handler); - if (!class_exists($controller) && !empty($this->namespace)) { - $controller = implode('\\', $this->namespace) . '\\' . $controller; - } - $this->handler = $this->getReflect($controller, $action); - } else if ($handler != null && !is_callable($handler, true)) { - $this->_error = 'Controller is con\'t exec.'; - } else if ($handler instanceof Closure) { - $this->handler = $handler; - } else { - [$controller, $action] = $this->handler = $handler; - if (!($controller instanceof Controller)) { - return $this; - } - $this->annotationInject($controller::class, $action); - } - if (!empty($this->handler)) { - $this->callback = Reduce::reduce($this->createDispatch(), $this->annotation()); - $this->setAop(); - } - return $this; - } - - private array $_aop; - - - /** - * @return Closure - * @throws Exception - */ - public function createDispatch(): Closure - { - $application = $this; - return static function () use ($application) { - $dispatchParam = Context::getContext('dispatch-param', [\request()]); - if (!empty($application->_aop)) { - return call_user_func($application->_aop[0], $application->_aop[1], $dispatchParam); - } - return call_user_func($application->handler, ...$dispatchParam); - }; - } - - - /** - * @throws ReflectionException - * @throws NotFindClassException - * @throws Exception - */ - private function setAop() - { - /** @var Aop $aop */ - $aop = Snowflake::app()->get('aop'); - if (!is_array($this->handler) || !$aop->hasAop($this->handler)) { - return; - } - $reflect = $aop->getAop($this->handler); - $this->_aop = [ - [$reflect->getMethod('invoke'), 'invokeArgs'], - $reflect->newInstance($this->handler) - ]; - } - - - private bool $_hasBeforeAction = false; - - - /** - * @return bool - * @throws Exception - */ - public function beforeAction(): bool - { - if (!$this->_hasBeforeAction) return true; - [$controller, $action] = $this->handler; - if (!$controller->beforeAction(\request())) { - return false; - } - return true; - } - - - /** - * @return array - */ - #[Pure] protected function annotation(): array - { - $middleWares = $this->getMiddleWares(); - $middleWares = $this->annotation_limit($this, $middleWares); - return $this->annotation_interceptor($this, $middleWares); - } - - - /** - * @param Node $node - * @param array $middleWares - * @return array - */ - #[Pure] protected function annotation_interceptor(Node $node, array $middleWares = []): array - { - if (!$node->hasInterceptor()) { - return $middleWares; - } - foreach ($node->getInterceptor() as $item) { - $middleWares[] = $item; - } - return $middleWares; - } - - - /** - * @param Node $node - * @param array $middleWares - * @return array - */ - #[Pure] protected function annotation_limit(Node $node, array $middleWares = []): array - { - if (!$node->hasLimits()) { - return $middleWares; - } - foreach ($node->getLimits() as $item) { - $middleWares[] = $item; - } - return $middleWares; - } - - - /** - * @return bool - */ - #[Pure] public function hasInterceptor(): bool - { - return count($this->_interceptors) > 0; - } - - - /** - * @return bool - */ - #[Pure] public function hasLimits(): bool - { - return count($this->_limits) > 0; - } - - - /** - * @param null $response - * @return mixed - * @throws Exception - */ - public function afterDispatch($response = null): mixed - { - if (is_object($this->_after[0])) { - return call_user_func($this->_after, \request(), $response); - } - foreach ($this->_after as $value) { - call_user_func($value, \request(), $response); - } - return $this->_after; - } - - - /** - * @return array - */ - public function getInterceptor(): array - { - return $this->_interceptors; - } - - - /** - * @return array - */ - public function getAfters(): array - { - return $this->_after; - } - - - /** - * @return bool - */ - #[Pure] public function hasAfter(): bool - { - return count($this->_after) > 0; - } - - - /** - * @return array - */ - public function getLimits(): array - { - return $this->_limits; - } - - /** - * @param Request $request - * @return bool - */ - public function methodAllow(Request $request): bool - { - if ($this->method == $request->getMethod()) { - return true; - } - return $this->method == 'any'; - } - - /** - * @return bool - * @throws Exception - */ - public function checkSuffix(): bool - { - if ($this->enableHtmlSuffix) { - $url = request()->getUri(); - $nowLength = strlen($this->htmlSuffix); - if (strpos($url, $this->htmlSuffix) !== strlen($url) - $nowLength) { - return false; - } - } - return true; - } - - - /** - * @param string $controller - * @param string $action - * @return null|array - * @throws Exception - */ - private function getReflect(string $controller, string $action): ?array - { - try { - $reflect = Snowflake::getDi()->getReflect($controller); - if (empty($reflect)) { - throw new Exception($controller . ' Class is con\'t Instantiable.'); - } - if (!empty($action) && !$reflect->hasMethod($action)) { - throw new Exception('method ' . $action . ' not exists at ' . $controller . '.'); - } - - $this->_hasBeforeAction = $reflect->hasMethod('beforeAction'); - - $this->annotationInject($reflect->getName(), $action); - - return [$reflect->newInstance(), $action]; - } catch (Throwable $exception) { - $this->_error = $exception->getMessage(); - $this->addError($exception, 'router'); - return null; - } - } - - - /** - * @param Closure|array|string $handler - * @throws Exception - */ - public function addInterceptor(Closure|string|array $handler) - { - if (!is_array($handler) || is_object($handler[0])) { - $handler = [$handler]; - } - foreach ($handler as $closure) { - if (in_array($closure, $this->_interceptors)) { - continue; - } - $this->_interceptors[] = $closure; - } - } - - - /** - * @param string $className - * @param string $action - * @return Node - * @throws Exception - */ - public function annotationInject(string $className, string $action): Node - { - $annotation = annotation()->getMethods($className, $action); - if (empty($annotation)) { - return $this; - } - foreach ($annotation as $attribute) { - if ($attribute instanceof Interceptor) { - $this->addInterceptor($attribute->interceptor); - } - if ($attribute instanceof After) { - $this->addAfter($attribute->after); - } - if ($attribute instanceof Middleware) { - $this->addMiddleware($attribute->middleware); - } - if ($attribute instanceof Limits) { - $this->addLimits($attribute->limits); - } - } - return $this; - } - - - /** - * @param Closure|array|string $handler - * @throws Exception - */ - public function addAfter(Closure|string|array $handler) - { - if (!is_array($handler) || is_object($handler[0])) { - $handler = [$handler]; - } - foreach ($handler as $closure) { - if (in_array($closure, $this->_after)) { - continue; - } - $this->_after[] = $closure; - } - } - - - /** - * @param Closure|array|string $handler - * @throws Exception - */ - public function addLimits(Closure|string|array $handler) - { - if (!is_array($handler) || is_object($handler[0])) { - $handler = [$handler]; - } - foreach ($handler as $closure) { - if (in_array($closure, $this->_limits)) { - continue; - } - $this->_limits[] = $closure; - } - } - - - /** - * @return string - * 错误信息 - */ - public function getError(): string - { - return $this->_error; - } - - /** - * @param Node $node - * @param string $field - * @return Node - */ - public function addChild(Node $node, string $field): Node - { - $field = (string)$field; - /** @var Node $oLod */ - $oLod = $this->childes[$field] ?? null; - if (!empty($oLod)) { - $node = $oLod; - } - $this->childes[$field] = $node; - return $this->childes[$field]; - } - - - /** - * @param string $search - * @return Node|null - * @throws Exception - */ - public function findNode(string $search): ?Node - { - if (empty($this->childes)) { - return null; - } - if (isset($this->childes[$search])) { - return $this->childes[$search]; - } - foreach ($this->childes as $key => $val) { - if ($search == $key) { - return $this->childes[$key]; - } - } - return null; - } - - - /** - * @param string $alias - * @return $this - * 别称 - */ - public function alias(string $alias): static - { - $this->_alias = $alias; - return $this; - } - - - /** - * @return string - */ - public function getAlias(): string - { - return $this->_alias; - } - - - /** - * @param Closure|array $class - * @return $this - */ - public function addMiddleware(Closure|array $class): static - { - if (empty($class)) return $this; - foreach ($class as $closure) { - if (in_array($closure, $this->middleware)) { - continue; - } - $this->middleware[] = $closure; - } - return $this; - } - - - /** - * @return array - */ - public function getMiddleWares(): array - { - return $this->middleware; - } - - - /** - * @return mixed - * @throws Exception - */ - public function dispatch(): mixed - { - Context::setContext('dispatch-param', func_get_args()); - if (empty($this->callback)) { - return Json::to(404, $this->errorMsg()); - } - return call_user_func($this->callback, \request()); - } - - - /** - * @return string - */ - private function errorMsg(): string - { - return $this->_error ?? 'Page not found.'; - } + public string $path = ''; + public int $index = 0; + public string $method = ''; + + /** @var Node[] $childes */ + public array $childes = []; + + public array $group = []; + + private string $_error = ''; + + private string $_dataType = ''; + + /** @var ?Closure|?array */ + public Closure|array|null $handler; + public string $htmlSuffix = '.html'; + public bool $enableHtmlSuffix = false; + public array $namespace = []; + public array $middleware = []; + + /** @var array|Closure */ + public Closure|array $callback = []; + + private string $_alias = ''; + + + /** + * @param string $dataType + */ + public function setDataType(string $dataType) + { + $this->_dataType = $dataType; + } + + + /** + * @param string $data + * @return mixed + */ + public function unpack(string $data): mixed + { + if ($this->_dataType == RpcProducer::PROTOCOL_JSON) { + return json_decode($data, true); + } + if ($this->_dataType == RpcProducer::PROTOCOL_SERIALIZE) { + return unserialize($data); + } + return $data; + } + + + /** + * @param $handler + * @return Node + * @throws + */ + public function bindHandler($handler): static + { + if (is_string($handler) && str_contains($handler, '@')) { + list($controller, $action) = explode('@', $handler); + if (!class_exists($controller) && !empty($this->namespace)) { + $controller = implode('\\', $this->namespace) . '\\' . $controller; + } + $this->handler = [Snowflake::getDi()->get($controller), $action]; + } else if ($handler != null && !is_callable($handler, true)) { + $this->_error = 'Controller is con\'t exec.'; + } else { + $this->handler = $handler; + } + if (!empty($this->handler)) { + $this->callback = di(Middlewares::class)->callerMiddlewares( + $this->handler[0], $this->handler[1], $this->createDispatch() + ); + } + return $this; + } + + + /** + * @throws ReflectionException + * @throws NotFindClassException + * @throws Exception + */ + private function createDispatch() + { + $application = $this; + + /** @var Aop $aop */ + $aop = Snowflake::app()->get('aop'); + if (!is_array($this->handler) || !$aop->hasAop($this->handler)) { + return static function () use ($application) { + $dispatchParam = Context::getContext('dispatch-param', [\request()]); + + return call_user_func($application->handler, ...$dispatchParam); + }; + } + + $reflect = $aop->getAop($this->handler); + $callback = [$reflect->getMethod('invoke'), 'invokeArgs']; + + return static function () use ($callback, $application, $reflect) { + $dispatchParam = Context::getContext('dispatch-param', [\request()]); + + $asp = $reflect->newInstance($this->handler); + + call_user_func($callback, $asp, $dispatchParam); + }; + } + + + /** + * @return array + */ + #[Pure] protected function annotation(): array + { + return $this->getMiddleWares(); + } + + + /** + * @param Request $request + * @return bool + */ + public function methodAllow(Request $request): bool + { + if ($this->method == $request->getMethod()) { + return true; + } + return $this->method == 'any'; + } + + /** + * @return bool + * @throws Exception + */ + public function checkSuffix(): bool + { + if ($this->enableHtmlSuffix) { + $url = request()->getUri(); + $nowLength = strlen($this->htmlSuffix); + if (strpos($url, $this->htmlSuffix) !== strlen($url) - $nowLength) { + return false; + } + } + return true; + } + + + /** + * @param Closure|array|string $handler + * @throws Exception + */ + public function addLimits(Closure|string|array $handler) + { + if (!is_array($handler) || is_object($handler[0])) { + $handler = [$handler]; + } + foreach ($handler as $closure) { + if (in_array($closure, $this->_limits)) { + continue; + } + $this->_limits[] = $closure; + } + } + + + /** + * @return string + * 错误信息 + */ + public function getError(): string + { + return $this->_error; + } + + /** + * @param Node $node + * @param string $field + * @return Node + */ + public function addChild(Node $node, string $field): Node + { + $field = (string)$field; + /** @var Node $oLod */ + $oLod = $this->childes[$field] ?? null; + if (!empty($oLod)) { + $node = $oLod; + } + $this->childes[$field] = $node; + return $this->childes[$field]; + } + + + /** + * @param string $search + * @return Node|null + * @throws Exception + */ + public function findNode(string $search): ?Node + { + if (empty($this->childes)) { + return null; + } + if (isset($this->childes[$search])) { + return $this->childes[$search]; + } + foreach ($this->childes as $key => $val) { + if ($search == $key) { + return $this->childes[$key]; + } + } + return null; + } + + + /** + * @param string $alias + * @return $this + * 别称 + */ + public function alias(string $alias): static + { + $this->_alias = $alias; + return $this; + } + + + /** + * @return string + */ + public function getAlias(): string + { + return $this->_alias; + } + + + /** + * @param Closure|array $class + * @return $this + */ + public function addMiddleware(Closure|array $class): static + { + if (empty($class)) return $this; + foreach ($class as $closure) { + if (in_array($closure, $this->middleware)) { + continue; + } + $this->middleware[] = $closure; + } + return $this; + } + + + /** + * @return array + */ + public function getMiddleWares(): array + { + return $this->middleware; + } + + + /** + * @return mixed + * @throws Exception + */ + public function dispatch(): mixed + { + Context::setContext('dispatch-param', func_get_args()); + if (empty($this->callback)) { + return Json::to(404, $this->errorMsg()); + } + return call_user_func($this->callback, \request()); + } + + + /** + * @return string + */ + private function errorMsg(): string + { + return $this->_error ?? 'Page not found.'; + } } diff --git a/HttpServer/Route/Reduce.php b/HttpServer/Route/Reduce.php index 2c3147b4..44173d72 100644 --- a/HttpServer/Route/Reduce.php +++ b/HttpServer/Route/Reduce.php @@ -19,52 +19,16 @@ class Reduce * @return mixed */ public static function reduce($last, $middleWares): mixed - { - return array_reduce(array_reverse($middleWares), static::core(), $last); - } - - - /** - * @param $middleWares - * @return mixed - */ - public static function after($middleWares): mixed { return array_reduce(array_reverse($middleWares), function ($stack, $pipe) { - return function ($request, $passable) use ($stack, $pipe) { - if (!($pipe instanceof After)) { - return call_user_func($pipe, $request, $passable, $stack); + return function ($passable) use ($stack, $pipe) { + if ($pipe instanceof Middleware) { + return $pipe->onHandler($passable, $stack); } - return $pipe->onHandler($request, $passable); + return call_user_func($pipe, $passable, $stack); }; - }); + }, $last); } - /** - * @return Closure - */ - private static function core(): Closure - { - return function ($stack, $pipe) { - return static::passable($stack, $pipe); - }; - } - - - /** - * @param $stack - * @param $pipe - * @return Closure - */ - public static function passable($stack, $pipe): Closure - { - return function ($passable) use ($stack, $pipe) { - if ($pipe instanceof Middleware) { - return $pipe->onHandler($passable, $stack); - } - return call_user_func($pipe, $passable, $stack); - }; - } - } diff --git a/HttpServer/Route/Router.php b/HttpServer/Route/Router.php index 623596d1..9573a123 100644 --- a/HttpServer/Route/Router.php +++ b/HttpServer/Route/Router.php @@ -44,6 +44,9 @@ class Router extends HttpService implements RouterInterface public int $useTree = ROUTER_TREE; + private static array $controllers = []; + + public ?Response $response = null; @@ -119,10 +122,6 @@ class Router extends HttpService implements RouterInterface $handler = Closure::bind($handler, new Controller()); } -// if ($this->useTree === ROUTER_TREE) { -// return $this->tree($path, $handler, $method); -// } - return $this->hash($path, $handler, $method); } @@ -136,7 +135,6 @@ class Router extends HttpService implements RouterInterface private function hash($path, $handler, string $method = 'any'): ?Node { $path = $this->resolve($path); - static::$nodes[$method][$path] = $this->NodeInstance($path, 0, $method); return static::$nodes[$method][$path]->bindHandler($handler); @@ -343,11 +341,9 @@ class Router extends HttpService implements RouterInterface if ($this->middleware instanceof \Closure) { $node->addMiddleware([$this->middleware]); } - if (is_array($name)) { $node->addMiddleware($this->resolve_middleware($name)); } - return $node; } @@ -527,10 +523,7 @@ class Router extends HttpService implements RouterInterface $this->response->setFormat(Response::HTML); $this->response->send('