From 9e6ac6d92d517262096fbad95b6132fb81dacf3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mr=C2=B7x?= Date: Tue, 23 Feb 2021 14:16:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Annotation/Annotation.php | 489 ++++++++++++++++--------------- Annotation/Route/After.php | 8 +- Annotation/Route/Interceptor.php | 8 +- Annotation/Route/Limits.php | 8 +- Annotation/Route/Middleware.php | 8 +- Annotation/Route/Route.php | 1 - HttpServer/Route/Middleware.php | 29 +- HttpServer/Route/Node.php | 3 + 8 files changed, 275 insertions(+), 279 deletions(-) diff --git a/Annotation/Annotation.php b/Annotation/Annotation.php index a43bd20d..3278b871 100644 --- a/Annotation/Annotation.php +++ b/Annotation/Annotation.php @@ -21,275 +21,298 @@ use Snowflake\Snowflake; class Annotation extends Component { - private array $_annotations = []; + private array $_annotations = []; - private array $_classes = []; + private array $_classes = []; - private array $_targets = []; + private array $_targets = []; - private array $_methods = []; + private array $_methods = []; - /** - * @param array $handler - * @param $name - */ - public function addMethodAttribute(array $handler, $name) - { - $this->_methods[get_class($handler[0])][$name] = $handler; - } + /** + * @param array $handler + * @param $name + */ + public function addMethodAttribute(array $handler, $name) + { + $this->_methods[get_class($handler[0])][$name] = $handler; + } - /** - * @param string $className - * @return array 根据类名获取注解 - * 根据类名获取注解 - */ - public function getMethods(string $className): array - { - return $this->_methods[$className] ?? []; - } + /** + * @param string $className + * @return array 根据类名获取注解 + * 根据类名获取注解 + */ + public function getMethods(string $className): array + { + return $this->_methods[$className] ?? []; + } - /** - * @param string $path - * @param string $namespace - * @param string $alias - * @return $this - * @throws ReflectionException|NotFindPropertyException - */ - public function readControllers(string $path, string $namespace, string $alias = 'root'): static - { - return $this->scanDir(glob($path . '*'), $namespace, $alias); - } + /** + * @param string $path + * @param string $namespace + * @param string $alias + * @return $this + * @throws ReflectionException|NotFindPropertyException + */ + public function readControllers(string $path, string $namespace, string $alias = 'root'): static + { + return $this->scanDir(glob($path . '*'), $namespace, $alias); + } - /** - * @param string $alias - * @return array - */ - public function getAlias(string $alias = 'root'): array - { - if (!isset($this->_annotations[$alias])) { - return []; - } - return $this->_annotations[$alias]; - } + /** + * @param string $alias + * @return array + */ + public function getAlias(string $alias = 'root'): array + { + if (!isset($this->_annotations[$alias])) { + return []; + } + return $this->_annotations[$alias]; + } - /** - * @param array $paths - * @param string $namespace - * @param string $alias - * @return $this - * @throws ReflectionException|NotFindPropertyException - * @throws NotFindClassException - */ - private function scanDir(array $paths, string $namespace, string $alias): static - { - if (!isset($this->_annotations[$alias])) { - $this->_annotations[$alias] = []; - } - foreach ($paths as $path) { - $explode = explode('/', $path); + /** + * @param array $paths + * @param string $namespace + * @param string $alias + * @return $this + * @throws ReflectionException|NotFindPropertyException + * @throws NotFindClassException + */ + private function scanDir(array $paths, string $namespace, string $alias): static + { + if (!isset($this->_annotations[$alias])) { + $this->_annotations[$alias] = []; + } + foreach ($paths as $path) { + $explode = explode('/', $path); - $explode_pop = array_pop($explode); - if (is_file($path)) { - if (!str_contains($path, '.php')) { - continue; - } - $explode_pop = str_replace('.php', '', $explode_pop); - $this->getReflect($namespace . '\\' . $explode_pop, $alias); - } else { - $this->scanDir(glob($path . '/*'), $namespace . '\\' . $explode_pop, $alias); - } - } - return $this; - } + $explode_pop = array_pop($explode); + if (is_file($path)) { + if (!str_contains($path, '.php')) { + continue; + } + $explode_pop = str_replace('.php', '', $explode_pop); + $this->getReflect($namespace . '\\' . $explode_pop, $alias); + } else { + $this->scanDir(glob($path . '/*'), $namespace . '\\' . $explode_pop, $alias); + } + } + return $this; + } - /** - * @param string $class - * @param string $alias - * @return array - * @throws Exception - */ - private function getReflect(string $class, string $alias): array - { - try { - $reflect = $this->reflectClass($class); - if (empty($reflect) || !$reflect->isInstantiable()) { - return []; - } - $object = $reflect->newInstance(); - $this->resolveMethod($reflect, $class, $alias, $object); - return $this->targets($reflect); - } catch (\Throwable $throwable) { - $this->addError($throwable); - return []; - } - } + /** + * @param string $class + * @param string $alias + * @return array + * @throws Exception + */ + private function getReflect(string $class, string $alias): array + { + try { + $reflect = $this->reflectClass($class); + if (empty($reflect) || !$reflect->isInstantiable()) { + return []; + } + $object = $reflect->newInstance(); + $this->resolveMethod($reflect, $class, $alias, $object); + return $this->targets($reflect); + } catch (\Throwable $throwable) { + $this->addError($throwable); + return []; + } + } - /** - * @param ReflectionClass $reflect - * @param $class - * @param $alias - * @param $object - * @throws NotFindPropertyException - */ - private function resolveMethod(ReflectionClass $reflect, $class, $alias, $object) - { - foreach ($reflect->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { - if ($method->class != $class) { - continue; - } - $this->resolveAnnotations($method, $alias, $object); - } - $this->resolveProperty($reflect, $object); - } + /** + * @param ReflectionClass $reflect + * @param $class + * @param $alias + * @param $object + * @throws NotFindPropertyException + */ + private function resolveMethod(ReflectionClass $reflect, $class, $alias, $object) + { + foreach ($reflect->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { + if ($method->class != $class) { + continue; + } + $this->resolveAnnotations($method, $alias, $object); + } + $this->resolveProperty($reflect, $object); + } - /** - * @param ReflectionClass $reflectionClass - * @param $object - * @throws NotFindPropertyException - */ - private function resolveProperty(ReflectionClass $reflectionClass, $object) - { - $property = $reflectionClass->getProperties(); - foreach ($property as $value) { - if ($value->isStatic()) continue; - $attributes = $value->getAttributes(); - if (count($attributes) < 1) { - continue; - } - foreach ($attributes as $attribute) { - /** @var IAnnotation $annotation */ - $annotation = $this->instance($attribute); - if (empty($annotation)) { - continue; - } - $annotation = $annotation->execute([$object, $value->getName()]); - if ($value->isPublic()) { - $object->{$value->getName()} = $annotation; - } else { - $name = 'set' . ucfirst($value->getName()); - if (!method_exists($object, $name)) { - throw new NotFindPropertyException('set property need method ' . $name); - } - $object->$name($annotation); - } - } - } - } + /** + * @param ReflectionClass $reflectionClass + * @param $object + * @throws NotFindPropertyException + */ + private function resolveProperty(ReflectionClass $reflectionClass, $object) + { + $property = $reflectionClass->getProperties(); + foreach ($property as $value) { + if ($value->isStatic()) continue; + $attributes = $value->getAttributes(); + if (count($attributes) < 1) { + continue; + } + foreach ($attributes as $attribute) { + /** @var IAnnotation $annotation */ + $annotation = $this->instance($attribute); + if (empty($annotation)) { + continue; + } + $annotation = $annotation->execute([$object, $value->getName()]); + if ($value->isPublic()) { + $object->{$value->getName()} = $annotation; + } else { + $name = 'set' . ucfirst($value->getName()); + if (!method_exists($object, $name)) { + throw new NotFindPropertyException('set property need method ' . $name); + } + $object->$name($annotation); + } + } + } + } - /** - * @param string $class - * @return ReflectionClass|null - * @throws ReflectionException - */ - private function reflectClass(string $class): ?ReflectionClass - { - return Snowflake::getDi()->getReflect($class); - } + /** + * @param string $class + * @return ReflectionClass|null + * @throws ReflectionException + */ + private function reflectClass(string $class): ?ReflectionClass + { + return Snowflake::getDi()->getReflect($class); + } - /** - * @param ReflectionMethod $method - * @param $alias - * @param $object - * @return array - */ - private function resolveAnnotations(ReflectionMethod $method, $alias, $object): array - { - $attributes = $method->getAttributes(); - if (count($attributes) < 1) { - return []; - } + /** + * @param ReflectionMethod $method + * @param $alias + * @param $object + * @return array + */ + private function resolveAnnotations(ReflectionMethod $method, $alias, $object): array + { + $attributes = $method->getAttributes(); + if (count($attributes) < 1) { + return []; + } - foreach ($attributes as $attribute) { - /** @var IAnnotation $class */ - $class = $this->instance($attribute); - if ($class === null) { - continue; - } - $class->execute([$object, $method->getName()]); - } + $name = get_class($object) . '_' . $method->getName(); + if (!isset($this->_annotations[$alias])) { + $this->_annotations[$alias] = []; + } + if (!isset($this->_annotations[$alias][$name])) { + $this->_annotations[$alias][$name] = []; + } -// $tmp['handler'] = [$object, $method->getName()]; -// $tmp['attributes'] = $names; -// -// $this->_annotations[$alias][] = $tmp; + $array = []; + foreach ($attributes as $attribute) { + /** @var IAnnotation $class */ + $class = $this->instance($attribute); + if ($class === null) { + continue; + } + $array[] = $class->execute([$object, $method->getName()]); + } - return []; - } + $this->_annotations[$alias][$name][] = $array; + return []; + } - /** - * @param $className - * @param string $method - * @return array - */ - public function getByClass($className, $method = ''): array - { - if (!isset($this->_classes[$className])) { - return []; - } - if (empty($method)) { - return $this->_classes[$className]; - } - foreach ($this->_classes[$className] as $_method => $class) { - if ($method == $_method) { - return [$class]; - } - } - return []; - } + /** + * @param $class + * @param $method + * @param string $alias + * @return array|mixed + */ + public function getAnnotationByMethod($class, $method, $alias = '') + { + if (!isset($this->_annotations[$alias])) { + return []; + } + if (is_object($class)) { + $class = get_class($class); + } + return $this->_annotations[$alias][$class . '_' . $method] ?? []; + } - /** - * @param ReflectionClass $reflect - * @return array - */ - private function targets(ReflectionClass $reflect): array - { - $name = $reflect->getName(); - if (!isset($this->_classes[$name])) { - $this->_classes[$name] = []; - } - $attributes = $reflect->getAttributes(); - if (count($attributes) > 0) { - if (!isset($this->_targets[$name])) { - $this->_targets[$name] = []; - } - foreach ($attributes as $attribute) { - $class = $this->instance($attribute); - if ($class === null) { - continue; - } - $this->_targets[$name][] = $class; - } - } - return []; - } + /** + * @param $className + * @param string $method + * @return array + */ + public function getByClass($className, $method = ''): array + { + if (!isset($this->_classes[$className])) { + return []; + } + if (empty($method)) { + return $this->_classes[$className]; + } + foreach ($this->_classes[$className] as $_method => $class) { + if ($method == $_method) { + return [$class]; + } + } + return []; + } - /** - * @param ReflectionAttribute $attribute - * @return array|object|null - */ - private function instance(ReflectionAttribute $attribute): array|object|null - { - if (!class_exists($attribute->getName())) { - return null; - } - return $attribute->newInstance(); - } + /** + * @param ReflectionClass $reflect + * @return array + */ + private function targets(ReflectionClass $reflect): array + { + $name = $reflect->getName(); + if (!isset($this->_classes[$name])) { + $this->_classes[$name] = []; + } + $attributes = $reflect->getAttributes(); + if (count($attributes) > 0) { + if (!isset($this->_targets[$name])) { + $this->_targets[$name] = []; + } + foreach ($attributes as $attribute) { + $class = $this->instance($attribute); + if ($class === null) { + continue; + } + $this->_targets[$name][] = $class; + } + } + return []; + } + + + /** + * @param ReflectionAttribute $attribute + * @return array|object|null + */ + private function instance(ReflectionAttribute $attribute): array|object|null + { + if (!class_exists($attribute->getName())) { + return null; + } + return $attribute->newInstance(); + } } diff --git a/Annotation/Route/After.php b/Annotation/Route/After.php index 0422ca2e..020d3372 100644 --- a/Annotation/Route/After.php +++ b/Annotation/Route/After.php @@ -34,16 +34,10 @@ use Snowflake\Snowflake; /** * @param array $handler * @return array|string - * @throws ReflectionException - * @throws NotFindClassException */ public function execute(array $handler): array|string { - // TODO: Implement execute() method. - foreach ($this->after as $key => $item) { - $this->after[$key] = [Snowflake::createObject($item), 'onHandler']; - } - return $this->after; + return $this; } diff --git a/Annotation/Route/Interceptor.php b/Annotation/Route/Interceptor.php index ec2229d9..f4f3273c 100644 --- a/Annotation/Route/Interceptor.php +++ b/Annotation/Route/Interceptor.php @@ -34,16 +34,10 @@ use Snowflake\Snowflake; /** * @param array $handler * @return array|string - * @throws ReflectionException - * @throws NotFindClassException */ public function execute(array $handler): array|string { - // TODO: Implement execute() method. - foreach ($this->interceptor as $key => $item) { - $this->interceptor[$key] = [Snowflake::createObject($item), 'Interceptor']; - } - return $this->interceptor; + return $this; } } diff --git a/Annotation/Route/Limits.php b/Annotation/Route/Limits.php index 2e174b9c..2fb71cc3 100644 --- a/Annotation/Route/Limits.php +++ b/Annotation/Route/Limits.php @@ -34,16 +34,10 @@ use Snowflake\Snowflake; /** * @param array $handler * @return array|string - * @throws ReflectionException - * @throws NotFindClassException */ public function execute(array $handler): array|string { - // TODO: Implement execute() method. - foreach ($this->limits as $key => $item) { - $this->limits[$key] = [Snowflake::createObject($item), 'next']; - } - return $this->limits; + return $this; } diff --git a/Annotation/Route/Middleware.php b/Annotation/Route/Middleware.php index 23a069d9..4e41983f 100644 --- a/Annotation/Route/Middleware.php +++ b/Annotation/Route/Middleware.php @@ -35,16 +35,10 @@ use Snowflake\Snowflake; /** * @param array $handler * @return array|string - * @throws ReflectionException - * @throws NotFindClassException */ public function execute(array $handler): array|string { - // TODO: Implement execute() method. - foreach ($this->middleware as $key => $item) { - $this->middleware[$key] = [Snowflake::createObject($item), 'onHandler']; - } - return $this->middleware; + return $this; } diff --git a/Annotation/Route/Route.php b/Annotation/Route/Route.php index 8d055b2c..211211cd 100644 --- a/Annotation/Route/Route.php +++ b/Annotation/Route/Route.php @@ -40,7 +40,6 @@ use Annotation\IAnnotation; // TODO: Implement setHandler() method. $router = Snowflake::app()->getRouter(); - var_dump($this->uri, $handler, $this->method); $router->addRoute($this->uri, $handler, $this->method); return $router; diff --git a/HttpServer/Route/Middleware.php b/HttpServer/Route/Middleware.php index baa0c900..e9850a01 100644 --- a/HttpServer/Route/Middleware.php +++ b/HttpServer/Route/Middleware.php @@ -72,27 +72,22 @@ class Middleware } [$controller, $action] = $node->handler; $attributes = Snowflake::app()->getAttributes(); - $annotation = $attributes->getByClass(get_class($controller), $action); + $annotation = $attributes->getAnnotationByMethod($controller, $action, 'controllers'); if (count($annotation) < 1) { return; } - foreach ($annotation as $item) { - if (empty($item) || !isset($item['attributes'])) { - continue; + foreach ($annotation as $attribute) { + if ($attribute instanceof Interceptor) { + $node->addInterceptor($attribute->interceptor); } - foreach ($item['attributes'] as $attribute) { - if ($attribute instanceof Interceptor) { - $node->addInterceptor($attribute->interceptor); - } - if ($attribute instanceof After) { - $node->addAfter($attribute->after); - } - if ($attribute instanceof RMiddleware) { - $node->addMiddleware($attribute->middleware); - } - if ($attribute instanceof Limits) { - $node->addLimits($attribute->limits); - } + if ($attribute instanceof After) { + $node->addAfter($attribute->after); + } + if ($attribute instanceof RMiddleware) { + $node->addMiddleware($attribute->middleware); + } + if ($attribute instanceof Limits) { + $node->addLimits($attribute->limits); } } } diff --git a/HttpServer/Route/Node.php b/HttpServer/Route/Node.php index 76f42690..fec05db3 100644 --- a/HttpServer/Route/Node.php +++ b/HttpServer/Route/Node.php @@ -447,6 +447,9 @@ class Node extends HttpService if (empty($this->handler)) { return $this; } + if (!is_array($this->handler)) { + return $this; + } /** @var Middleware $made */ $made = Snowflake::createObject(Middleware::class); $made->getGenerate($this);