From f1a79281928d0b8c31dd2f79b3b9caec82e0b879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mr=C2=B7x?= Date: Mon, 2 Aug 2021 18:12:32 +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 --- HttpServer/Route/Node.php | 46 +++++++++++++++++++++++---------- System/Aop.php | 15 ++++------- System/Di/Attributes.php | 11 ++++++++ System/Di/Container.php | 48 ++++++++++++++++++++++++++++------- System/Error/LoggerAspect.php | 5 ++-- System/IAspect.php | 11 ++++---- 6 files changed, 97 insertions(+), 39 deletions(-) diff --git a/HttpServer/Route/Node.php b/HttpServer/Route/Node.php index e30076cb..7ff6cf6f 100644 --- a/HttpServer/Route/Node.php +++ b/HttpServer/Route/Node.php @@ -9,7 +9,6 @@ use Annotation\Route\RpcProducer; use Closure; use Exception; use HttpServer\Abstracts\HttpService; -use HttpServer\Http\Context; use HttpServer\Http\Request; use JetBrains\PhpStorm\Pure; use ReflectionClass; @@ -17,6 +16,7 @@ use ReflectionException; use Snowflake\Aop; use Snowflake\Core\Json; use Snowflake\Exception\NotFindClassException; +use Snowflake\IAspect; use Snowflake\Snowflake; /** @@ -118,13 +118,35 @@ class Node extends HttpService $this->handler[0], $this->handler[1], $this->createDispatch() ); } + $this->setParameters($this->handler); return $this; } + private array $_injectParameters = []; + + /** * @throws ReflectionException * @throws NotFindClassException + */ + private function setParameters($handler) + { + $container = Snowflake::getDi(); + if ($handler instanceof Closure) { + $this->_injectParameters = $container->resolveFunctionParameters($handler); + } else { + [$controller, $action] = $this->handler; + if (is_object($controller)) { + $controller = get_class($controller); + } + $this->_injectParameters = $container->getMethodParameters($controller, $action); + } + } + + + /** + * @throws ReflectionException * @throws Exception */ private function createDispatch(): Closure @@ -134,24 +156,21 @@ class Node extends HttpService if ($this->handler instanceof Closure || !$aop->hasAop($this->handler)) { return $this->normalHandler($this->handler); } else { - return $this->aopHandler($aop->getAop($this->handler), $this); + return $this->aopHandler($aop->getAop($this->handler)); } } /** - * @param ReflectionClass $reflect - * @param $application + * @param IAspect $reflect * @return Closure - * @throws ReflectionException|NotFindClassException */ - private function aopHandler(ReflectionClass $reflect, $application): Closure + private function aopHandler(IAspect $reflect): Closure { - $callback = [$reflect->getMethod('invoke'), 'invokeArgs']; - - $instance = Snowflake::getDi()->get($reflect->getName()); - return static function () use ($callback, $application, $instance, $reflect) { - call_user_func($callback, $instance); + $params = $this->_injectParameters; + $handler = $this->handler; + return static function () use ($reflect, $handler, $params) { + return $reflect->invoke($handler, $params); }; } @@ -162,8 +181,9 @@ class Node extends HttpService */ private function normalHandler($handler): Closure { - return static function () use ($handler) { - return call_user_func($handler); + $params = $this->_injectParameters; + return static function () use ($handler, $params) { + return call_user_func($handler, ...$params); }; } diff --git a/System/Aop.php b/System/Aop.php index 26786d93..401fc9ea 100644 --- a/System/Aop.php +++ b/System/Aop.php @@ -5,11 +5,9 @@ namespace Snowflake; use Exception; -use Reflection; use ReflectionClass; use ReflectionException; use Snowflake\Abstracts\Component; -use Snowflake\Exception\NotFindClassException; defined('ASPECT_ERROR') or define('ASPECT_ERROR', 'Aspect annotation must implement '); @@ -57,7 +55,6 @@ class Aop extends Component * @param $handler * @param $params * @return mixed - * @throws NotFindClassException * @throws ReflectionException * @throws Exception */ @@ -75,20 +72,18 @@ class Aop extends Component } - /** * @param array $handler - * @return ReflectionClass - * @throws NotFindClassException - * @throws ReflectionException + * @return IAspect * @throws Exception + * @throws ReflectionException */ - public function getAop(array $handler): ReflectionClass + public function getAop(array $handler): IAspect { $aopName = $handler[0]::class . '::' . $handler[1]; - $reflect = Snowflake::getDi()->getReflect(current(static::$_aop[$aopName])); - if (!$reflect->isInstantiable() || !$reflect->hasMethod('invoke')) { + $reflect = Snowflake::getDi()->get(current(static::$_aop[$aopName])); + if (!method_exists($reflect, 'invoke')) { throw new Exception(ASPECT_ERROR . IAspect::class); } return $reflect; diff --git a/System/Di/Attributes.php b/System/Di/Attributes.php index a703c06e..350f8363 100644 --- a/System/Di/Attributes.php +++ b/System/Di/Attributes.php @@ -70,6 +70,17 @@ trait Attributes } + /** + * @param string $class + * @param string $method + * @return bool + */ + public function hasMethod(string $class, string $method): bool + { + return isset($this->_classMethod[$class]) && isset($this->_classMethod[$class][$method]); + } + + /** * @param ReflectionClass $class * @return array diff --git a/System/Di/Container.php b/System/Di/Container.php index b83ae9c9..67a22300 100644 --- a/System/Di/Container.php +++ b/System/Di/Container.php @@ -14,6 +14,7 @@ use Exception; use JetBrains\PhpStorm\Pure; use ReflectionClass; use ReflectionException; +use ReflectionFunction; use ReflectionMethod; use ReflectionProperty; use Snowflake\Abstracts\BaseObject; @@ -280,26 +281,55 @@ class Container extends BaseObject if (!($reflectMethod instanceof ReflectionMethod)) { throw new ReflectionException("Class does not have a function $className::$method"); } - return $this->resolveMethodParameters($reflectMethod); + $className = $reflectMethod->getDeclaringClass()->getName(); + if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$reflectMethod->getName()])) { + return $this->_parameters[$className][$reflectMethod->getName()]; + } + return $this->setParameters($className, $reflectMethod->getName(), $this->resolveMethodParameters($reflectMethod)); } /** - * @param ReflectionMethod $reflectionMethod + * @param $class + * @param $method + * @param $parameters + */ + private function setParameters($class, $method, $parameters) + { + if (!isset($this->_parameters[$class])) { + $this->_parameters[$class] = []; + } + if (!isset($this->_parameters[$class][$method])) { + $this->_parameters[$class][$method] = []; + } + return $this->_parameters[$class][$method] = $parameters; + } + + + /** + * @param \Closure $reflectionMethod * @return array * @throws NotFindClassException * @throws ReflectionException */ - private function resolveMethodParameters(ReflectionMethod $reflectionMethod): array + public function resolveFunctionParameters(\Closure $reflectionMethod): array + { + return $this->resolveMethodParameters(new ReflectionFunction($reflectionMethod)); + } + + + /** + * @param ReflectionMethod|ReflectionFunction $reflectionMethod + * @return array + * @throws NotFindClassException + * @throws ReflectionException + */ + private function resolveMethodParameters(ReflectionMethod|ReflectionFunction $reflectionMethod): array { - $className = $reflectionMethod->getDeclaringClass()->getName(); - if (isset($this->_parameters[$className]) && isset($this->_parameters[$className][$reflectionMethod->getName()])) { - return $this->_parameters[$className][$reflectionMethod->getName()]; - } if ($reflectionMethod->getNumberOfParameters() < 1) { return []; } - $this->_parameters[$className][$reflectionMethod->getName()] = $params = []; + $params = []; foreach ($reflectionMethod->getParameters() as $key => $parameter) { if ($parameter->isDefaultValueAvailable()) { $params[$key] = $parameter->getDefaultValue(); @@ -317,7 +347,7 @@ class Container extends BaseObject }; } } - return $this->_parameters[$className][$reflectionMethod->getName()] = $params; + return $params; } diff --git a/System/Error/LoggerAspect.php b/System/Error/LoggerAspect.php index 7d9961f1..e4c602a6 100644 --- a/System/Error/LoggerAspect.php +++ b/System/Error/LoggerAspect.php @@ -20,13 +20,14 @@ class LoggerAspect implements IAspect /** * @param mixed $handler + * @param array $params * @return mixed */ - public function invoke(mixed $handler): mixed + public function invoke(mixed $handler, array $params = []): mixed { $startTime = microtime(true); - $data = call_user_func($handler); + $data = call_user_func($handler, ...$params); $this->print_runtime($handler, $startTime); diff --git a/System/IAspect.php b/System/IAspect.php index e946095d..9bfddfc0 100644 --- a/System/IAspect.php +++ b/System/IAspect.php @@ -8,10 +8,11 @@ interface IAspect { - - /** - * @return mixed|void - */ - public function invoke(mixed $handler); + /** + * @param mixed $handler + * @param array $params + * @return mixed + */ + public function invoke(mixed $handler, array $params = []): mixed; }