From b0cbcb0caa1b475e5472434b07c3becc884581dc Mon Sep 17 00:00:00 2001 From: "as2252258@163.com" Date: Mon, 29 Mar 2021 03:09:55 +0800 Subject: [PATCH] modify --- Annotation/Aspect.php | 19 ++++++++-- System/Aop.php | 65 +++++++++++++++++++++++++++++++++++ System/Error/LoggerAspect.php | 55 +++++++++++++++++++++++++++++ System/IAspect.php | 23 +++++++++++++ 4 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 System/Aop.php create mode 100644 System/Error/LoggerAspect.php create mode 100644 System/IAspect.php diff --git a/Annotation/Aspect.php b/Annotation/Aspect.php index 91775dd2..5baea1dd 100644 --- a/Annotation/Aspect.php +++ b/Annotation/Aspect.php @@ -4,18 +4,25 @@ namespace Annotation; +use Snowflake\Aop; +use Snowflake\IAspect; +use Snowflake\Snowflake; + +defined('ASPECT_ERROR') or define('ASPECT_ERROR', 'Aspect annotation must implement '); + /** * Class Aspect * @package Annotation */ -#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_FUNCTION)] class Aspect extends Attribute +#[\Attribute(\Attribute::TARGET_METHOD)] class Aspect extends Attribute { /** * Aspect constructor. + * @param string $aspect */ - public function __construct() + public function __construct(public string $aspect) { } @@ -26,6 +33,14 @@ namespace Annotation; */ public function execute(array $handler): mixed { + if (!in_array(IAspect::class, class_implements($this->aspect))) { + throw new \Exception(ASPECT_ERROR . IAspect::class); + } + /** @var Aop $aop */ + $aop = Snowflake::app()->get('aop'); + + $aop->aop_add($handler, $this->aspect); + return parent::execute($handler); // TODO: Change the autogenerated stub } diff --git a/System/Aop.php b/System/Aop.php new file mode 100644 index 00000000..426cf69c --- /dev/null +++ b/System/Aop.php @@ -0,0 +1,65 @@ +_aop[$aspect])) { + $this->_aop[$aspect] = []; + } + + $this->_aop[get_class($class) . '::' . $method][] = $aspect; + } + + + /** + * @return mixed|void + * @throws \ReflectionException + */ + final public function dispatch() + { + $get_args = func_get_args(); + [$class, $method] = array_shift($get_args); + + $aopName = get_class($class) . '::' . $method; + if (!isset($this->_aop[$aopName])) { + return call_user_func($get_args, ...$get_args); + } + + $reflect = new \ReflectionClass($this->_aop[$aopName]); + if (!$reflect->hasMethod('invoke')) { + throw new \Exception(ASPECT_ERROR . IAspect::class); + } + $method = $reflect->getMethod('invoke'); + + $data = $method->invokeArgs($reflect->newInstance([$class, $method]), $get_args); + if ($method->getReturnType() !== null) { + return $data; + } + } + + +} diff --git a/System/Error/LoggerAspect.php b/System/Error/LoggerAspect.php new file mode 100644 index 00000000..e6048b17 --- /dev/null +++ b/System/Error/LoggerAspect.php @@ -0,0 +1,55 @@ +className = get_class($this->handler[0]); + $this->methodName = $this->handler[1]; + } + + + /** + * @return mixed|void + */ + public function invoke() + { + $startTime = microtime(true); + + $data = call_user_func($this->handler, func_get_args()); + + $this->print_runtime($startTime); + + return $data; + } + + + private function print_runtime($startTime) + { + $runTime = round(microtime(true) - $startTime, 6); + echo sprintf('run %s::%s use time %6f', $this->className, $this->methodName, $runTime); + echo PHP_EOL; + } + + +} diff --git a/System/IAspect.php b/System/IAspect.php new file mode 100644 index 00000000..b8a8b692 --- /dev/null +++ b/System/IAspect.php @@ -0,0 +1,23 @@ +