前言随着Swoole的不断迭代,一些Swoole协程框架也逐渐进入了大家的视野,比如:Hyperf、Swoft等;常驻内存的实现让PHP性能比传统的PHP-FPM模式的框架有了质的提升。根据Swoole开源框架,提供完善的开发组件。看过或用过Hyperf和Swoft框架的朋友应该知道,在这些框架中,也有类似于SpringCloud框架的灵活框架。注解,本文用一个简单的demo实现了一个注解,让大家更快速的理解注解。什么是注释注释定义为:附加到数据/代码的元数据。框架可以根据这些元信息为代码提供各种附加功能。本质上,注解是要理解注解只是另一种显示配置的方式。注释的工作原理如何在代码中识别注释以及如何调用它们?带着问题一起看代码吧,GitHub:https://github.com/LoyaltyLu/annotation_demo这是我写的一个demo,里面有注释和一个实现容器的简单例子,供大家参考,看文章之前是建议大家先阅读这两篇文档:DoctrineAnnotationsPHPReflectionCodeAnalysisAnnotationCollection通过demo让你简单了解注解是如何收集的。类注解集合index.phpgetClassAnnotations($重新);foreach($class_annosas$class_anno){$routePrefix=$class_anno->getPrefix();}//通过反射获取所有方法$refMethods=$re->getMethods();foreach($refMethodsas$method){$methodAnnos=$reader->getMethodAnnotations($method);}foreach($methodAnnosas$methodAnno){$routePath=$methodAnno->getRoute();}//把一些逻辑放在一个解析类中处理逻辑//$re->newInstance();反射实例化(newRequestMappingParser())->parse($routePrefix,$routePath,$re->newInstance(),$method->name);}}}。.....如何自定义规则?可以参考文档。规则存放在:./Annotation/Mapping/目录;AnnotationReader类中的getClassAnnotations($re)方法需要反射类。更多反射请参考PHPReflection;手动实例化类:$obj=new\App\Http\Controller\HomeController();然后获取反射类:$re=new\ReflectionClass($obj);因为是demo,并没有太复杂,所以可以在这里继续完善,调用getClassAnnotations($re)方法获取类的所有注解$class_annos=$reader->getClassAnnotations($re);打印$class_annos的结果如下:rray(1){[0]=>object(Annotation\Mapping\Controller)#15(1){["prefix":"Annotation\Mapping\Controller":private]=>string(6)"/index"}这个结果的参数在哪里获取?接下来看实例化的HomeController和定义的注解规则类Annotation\Mapping\Controller;Annotation\Mapping\Controller.phpprefix=$values['value'];}if(isset($values['prefix'])){$this->prefix=$values['prefix'];}}publicfunctiongetPrefix():string{return$this->prefix;}}为了节省篇幅,这里删除了一些无用的代码和注释。可以去github上查看注解类中的类注解,就是设置规则的地方:/***ClassController*@Annotation*@Target("CLASS")*@Attributes({*@Attribute("prefix",type="string"),*})*@since2.0*/@Target表示适用注解类型的type元素然后,你可以定义一个或多个目标:CLASS允许docblockPROPERTY类中允许docblockMETHOD属性中允许docblockALL方法中允许docblockANNOTATION类中允许docblockANNOTATION属性和方法允许其他注解更多介绍请移步DoctrineAnnotationsHomeController.phpobject(Annotation\Mapping\Controller)#15(1){["prefix":"Annotation\Mapping\Controller":private]=>string(6)"/index"}}到集合这样注解就完成了,方法注解获取逻辑和类注解获取逻辑基本一致。方法注解收集:类注解收集完成后,我们可以继续使用反射类获取所有类中的方法。具体操作如下:$obj=new\App\Http\Controller\HomeController();$re=new\ReflectionClass($obj);//获取类注解$class_annos=$reader->getClassAnnotations($re);foreach($class_annosas$class_anno){$routePrefix=$class_anno->getPrefix();//获取所有注解//通过反射获取所有方法$refMethods=$re->getMethods();foreach($refMethodsas$method){$methodAnnos=$reader->getMethodAnnotations($method);}foreach($methodAnnosas$methodAnno){$routePath=$methodAnno->getRoute();}//把一些逻辑放在一个解析类中处理逻辑//$re->newInstance();反射实例化(newRequestMappingParser())->parse($routePrefix,$routePath,$re->newInstance(),$method->name)}}}通过反射类中的getMethods方法获取类中的所有方法,var_dump($refMethods)数据如下:array(2){[0]=>object(ReflectionMethod)#16(2){["name"]=>string(5)"index"["class"]=>string(34)"App\Http\Controller\HomeController"}[1]=>object(ReflectionMethod)#13(2){["name"]=>string(2)"demo"["class"]=>string(34)"App\Http\Controller\HomeController"}}使用注解类的getMethodAnnotations($method);该方法可以根据设置的方法读取各个方法设置的注解,获取注解规则:array(1){[0]=>object(Annotation\Mapping\RequestMapping)#18(1){["route":"Annotation\Mapping\RequestMapping":private]=>string(5)"/test"}}array(1){[0]=>object(Annotation\Mapping\RequestMapping)#14(1){["路由":"Annotation\Mapping\RequestMapping":private]=>string(5)"/demo"}}方法注解收集规则配置:/***HTTP动作方法注解*@Annotation*@Target("METHOD")**@since2.0*/classRequestMapping{......}至此已经完成了注解的所有收集工作,后面的话就是业务处理逻辑,如何分配路由等,大家可以先看看源码里的demo,稍后我会写一个注释来调用结论。这是我自己学习过程中的一点小总结。文章中有错误的地方请大家帮忙指出,及时改正,希望对大家有所帮助。这是2020年的第一篇文章,相信这只是一个开始。春节马上就要到了。在此祝大家新年快乐,身体健康,工资双倍提前~谢谢~
