在阅读TP框架源码中,发现TP框架支持使用注解方式定义路由(也称为注解路由),类似于Java中注解,默认关闭,如果需要开启在路由配置文件中设置:
1 | // 开启注解路由 |
然后只需要直接在控制器类的方法注释中定义,例如:
1 |
|
@route(‘hello/:name’) 就是注解路由的内容,然后就使用下面的URL地址访问:
页面输出:
hello,thinkphp
注解路由使路由定义更为方便,但PHP本身没有类似于Java的Annotation机制,那是如何实现的呢?这就不得不说到PHP的反射机制。
反射
PHP自5.0版本以后添加了反射机制,它提供了一套强大的反射API,允许你在PHP运行环境中,对类、接口、函数、方法和扩展进行逆向分析,经常用于高扩展的PHP框架,自动加载插件,自动生成文档等。
在TP5框架中,注解路由都是基于PHP反射来实现,大概思路如下:
- 通过反射类获取类的所有public方法;
- 分析每个public方法的文档注释,如果含有特定路由标志,则将该方法作为路由处理函数
注解路由实现
下面,我们模拟实现注解路由。先定义一个控制器类 controller/User.php
:
1 |
|
在User控制器中,定义了两个方法,对应两条路由@route('/user/login')
和 @route('/user/info')
。从语法层面来讲,这些都只是普通的文档注释,但是我们可以通过解析路由标志和控制器方法,将其关联起来,那我们就可以在特定路由下调用特定控制器方法来处理请求。例如:当请求index.php?s=/user/login时会执行User控制器中login方法。
通常情况下,我们都会将控制器类都统一放在某一个目录下,如controller, 我们分析controller目录下每个控制类中的public方法的文档注释,将含有@route路由标志的方法和路由信息关联起来。
1 |
|
就这样,我们基本上模拟出了TP框架(URL兼容模式)下的注解路由实现。
弊端
Java由于本身语言特性导致非常适合用注解方式来开发,但PHP本身如果用注解路由,不得不使用反射。用反射的话,那性能自然就降低,不得不用cache(缓存路由信息,不然每次都得分析注解),同时也不便于统一管理URl,所以在TP框架中注解路由并不是默认开启。