├── .gitignore ├── examples ├── TestBase.php ├── main.php └── TestClass.php ├── composer.json ├── README.md └── src ├── AnnotationAbstract.php ├── Directory.php └── AnnotationService.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | .idea 3 | 4 | -------------------------------------------------------------------------------- /examples/TestBase.php: -------------------------------------------------------------------------------- 1 | setPsr4("", __DIR__); 14 | 15 | $directory = new \Tool\Annotation\AnnotationService(); 16 | // 设置遍历目录 17 | $scanDir = realpath(__DIR__); 18 | $directory->setScanDirectory($scanDir,""); 19 | // 设置注解标签 20 | $directory->setAnnotation('TestBase',TestBase::class); 21 | 22 | foreach ($directory->eachAnnotation() as $annotation){ 23 | if( $annotation instanceof TestBase){ 24 | // 是TestBase注解 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/TestClass.php: -------------------------------------------------------------------------------- 1 | setScanDirectory($scanDir,""); 10 | // 设置注解标签,绑定注解tag到类 11 | $directory->setAnnotation('TestBase',TestBase::class); 12 | $directory->setAnnotation('TestBase2',TestBase2::class); 13 | 14 | foreach ($directory->eachAnnotation() as $annotation){ 15 | if( $annotation instanceof TestBase){ 16 | // 是TestBase注解 17 | } 18 | } 19 | ~~~~ 20 | 21 | 定义TestBase注解 22 | ~~~~ 23 | class TestBase extends \Tool\Annotation\AnnotationAbstract 24 | { 25 | public $one; 26 | 27 | function init(...$params) 28 | { 29 | // @TestBase("参数1","参数2") 注解的参数将会传入这里 30 | $this->one = $params[0]; 31 | } 32 | } 33 | ~~~~ 34 | 35 | 逻辑中使用注解 36 | 37 | ~~~~ 38 | class TestClass 39 | { 40 | /** 41 | * @TestBase(1) 42 | * @param null $time 43 | */ 44 | public function testFunc($time=null) 45 | { 46 | var_dump($time); 47 | } 48 | 49 | /** 50 | * @TestMapping($route="/user","/test") 51 | * @param string $route 52 | * @param string $middleware 53 | */ 54 | public static function testStatic($route='',$middleware) 55 | { 56 | var_dump($route,$middleware); 57 | } 58 | 59 | /** 60 | * @TestMapping($route="/user","/test") 61 | * @isBase 62 | * @param string $route 63 | * @param string $middleware 64 | */ 65 | public static function testBase($route='',$middleware) 66 | { 67 | var_dump($route,$middleware); 68 | } 69 | } 70 | ~~~~ -------------------------------------------------------------------------------- /src/AnnotationAbstract.php: -------------------------------------------------------------------------------- 1 | atClass = $atClass; 32 | } 33 | 34 | public final function setMethod(\ReflectionFunctionAbstract $atMethod) 35 | { 36 | $this->atMethod = $atMethod; 37 | } 38 | 39 | public function getTitle($strLen=null) 40 | { 41 | $title = $this->atMethod->getDocComment(); 42 | $arr = explode("@",$title); 43 | $title = reset($arr); 44 | $title = str_replace(['*',"\n","\r","/"],'',$title); 45 | $title = trim($title); 46 | if( $strLen ){ 47 | return mb_substr($title,0,$strLen); 48 | } 49 | return $title; 50 | } 51 | 52 | public function getKey() 53 | { 54 | 55 | } 56 | 57 | public function call(...$params) 58 | { 59 | try{ 60 | $class = $this->atClass->getName(); 61 | $func = $this->atMethod->getName(); 62 | call_user_func_array([$class,$func],$params); 63 | }catch (\Exception $exception){ 64 | 65 | } 66 | } 67 | 68 | abstract function init(...$params); 69 | } -------------------------------------------------------------------------------- /src/Directory.php: -------------------------------------------------------------------------------- 1 | dirBindNameSpace[$directory] = $nameSpace; 28 | } 29 | 30 | /** 31 | * 遍历目录下所有类 32 | * 33 | * @return \Generator 34 | */ 35 | public function scanClass() 36 | { 37 | foreach ($this->dirBindNameSpace as $directory => $nameSpace) { 38 | foreach ($this->scanNameSpace($directory,$nameSpace) as $class) { 39 | yield $class; 40 | } 41 | } 42 | } 43 | 44 | /** 45 | * 遍历命名空间 46 | * 47 | * @param $directory 48 | * @param $nameSpace 49 | * @return \Generator 50 | */ 51 | private function scanNameSpace($directory,$nameSpace) 52 | { 53 | if ($dh = opendir($directory)) { 54 | while (($file = readdir($dh)) !== false) { 55 | if (in_array($file, ['.', '..'])) { 56 | continue; 57 | } elseif (is_dir($directory . DIRECTORY_SEPARATOR . $file)) { 58 | foreach ($this->scanNameSpace($directory . DIRECTORY_SEPARATOR . $file,$nameSpace.$file."\\") as $arrValue){ 59 | yield $arrValue; 60 | } 61 | } elseif (substr($file, -4) == '.php') { 62 | yield $nameSpace.pathinfo($file,PATHINFO_FILENAME); 63 | } 64 | } 65 | closedir($dh); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /src/AnnotationService.php: -------------------------------------------------------------------------------- 1 | dirService = new Directory(); 25 | } 26 | 27 | public function setScanDirectory($directory, $nameSpace) 28 | { 29 | $this->dirService->setScanDirectory($directory, $nameSpace); 30 | } 31 | 32 | public function setAnnotation($tagName, $bindClass) 33 | { 34 | $this->bindTag[$tagName] = $bindClass; 35 | } 36 | 37 | public function eachAnnotation() 38 | { 39 | foreach ($this->dirService->scanClass() as $class) { 40 | if( class_exists($class) ){ 41 | $reflection = new \ReflectionClass($class); 42 | foreach ($reflection->getMethods() as $method) { 43 | $doc = $method->getDocComment(); 44 | if (preg_match_all("/@\w+\([^\r\n]+/is", $doc, $match)) { 45 | foreach (reset($match) as $docFun) { 46 | $docFun = substr($docFun, 0, strrpos($docFun, ')')); 47 | $docFun = str_replace("\"*\\", "\"*\\\\", $docFun); 48 | foreach ($this->bindTag as $tabName => $annotationClass) { 49 | if (strpos($docFun, "@{$tabName}(") === 0) { 50 | /** @var AnnotationAbstract $annotation */ 51 | $annotation = new $annotationClass(self::getParams(str_replace("@{$tabName}(", "", $docFun))); 52 | $annotation->setClass($reflection); 53 | $annotation->setMethod($method); 54 | yield $annotation; 55 | } 56 | } 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | 64 | protected static function getParams(string $param) 65 | { 66 | $arrParams = eval("return [{$param}];"); 67 | return $arrParams; 68 | } 69 | 70 | /** 71 | * @param $key 72 | * @return AnnotationAbstract 73 | */ 74 | public function get($key) 75 | { 76 | return $this->annotation[$key] ?? null; 77 | } 78 | } --------------------------------------------------------------------------------