企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### 资源路由 前面我们已经了解了别名路由的强大之处,但别名路由的缺陷就在于单个路由规则的灵活性不够,而资源路由则默认生成了一套路由规则,可以用于快速生成RESTful的路由。 #### RESTful 要理解资源路由就要理解什么是RESTful。如果一个架构符合REST(即Representational State Transfer的缩写,意为表现层状态转化)原则,就称它为RESTful架构。 REST提出了一些设计概念和准则: 1、网络上的所有事物都被抽象为资源(resource); 2、每个资源对应一个唯一的资源标识(resource identifier); 3、通过通用的连接器接口(generic connector interface)对资源进行操作; 4、对资源的各种操作不会改变资源标识; 5、所有的操作都是无状态的(stateless)。 需要注意的是,REST是设计风格而不是标准。REST通常基于使用HTTP,URI,和XML以及HTML这些现有的广泛流行的协议和标准。 传统的请求模式和REST模式的请求模式区别: |作用 |传统模式 |REST模式| |--|--|--| |列举出所有的用户 |GET /users/list |GET /users| |列出ID为1的用户信息 |GET /users/show/id/1 |GET /users/1| |插入一个新的用户 |POST /users/add |POST /users| |更新ID为1的用户信息 |POST /users/mdy/id/1 |PUT /users/1| |删除ID为1的用户 |POST /users/delete/id/1 |DELETE /users/1| #### 资源路由定义 现在再来理解什么是资源路由,资源路由的作用就是快速给控制器生成一套RESTful架构的路由规范。 ThinkPHP5.0可以通过命令行快速生成一个RESTful控制器,我们进入命令行,切换到应用根目录下面,执行下面的指令: ~~~ php think make:controller index/Blog ~~~ 会自动生成一个类名是`app\index\controller\Blog`的资源控制器类(采用RESTful架构的控制器),并且会自动生成对应的7个(空白)方法,代码如下: ~~~ <?php namespace app\index\controller; use think\Controller; use think\Request; class Blog extends Controller { /** * 显示资源列表 * * @return \think\Response */ public function index() { // } /** * 显示创建资源表单页. * * @return \think\Response */ public function create() { // } /** * 保存新建的资源 * * @param \think\Request $request * @return \think\Response */ public function save(Request $request) { // } /** * 显示指定的资源 * * @param int $id * @return \think\Response */ public function read($id) { // } /** * 显示编辑资源表单页. * * @param int $id * @return \think\Response */ public function edit($id) { // } /** * 保存更新的资源 * * @param \think\Request $request * @param int $id * @return \think\Response */ public function update(Request $request, $id) { // } /** * 删除指定资源 * * @param int $id * @return \think\Response */ public function delete($id) { // } } ~~~ 但是你会看到,这些操作方法本身并不会进行请求类型的判断,这些是需要配合路由规则来完成的,也就是说我们需要给Blog控制器添加`RESTful`的路由访问规则,看起来像下面一样: |请求类型 |路由规则 |对应操作方法| 描述| |--|--|--|--| |GET |blogs |index/Blog/index |显示博客列表| |GET |blogs/create |index/Blog/create |新增博客页面| |POST |blogs |index/Blog/save |保存博客内容| |GET |blogs/:id |index/Blog/read |查看博客内容| |GET| blogs/:id/edit| index/Blog/edit |编辑博客页面| |PUT| blogs/:id |index/Blog/update| 更新博客内容| |DELETE |blogs/:id |index/Blog/delete |删除博客| > 这里使用了复数方式的blogs,这是RESTful的一种建议规范。 按照之前学习的方法可能需要一个个注册,类似下面: ~~~ Route::get('blogs','index/Blog/index'); Route::get('blogs/create','index/Blog/create'); Route::post('blogs','index/Blog/save'); Route::get('blogs/:id','index/Blog/read'); Route::get('blogs/:id/edit','index/Blog/edit'); Route::put('blogs/:id','index/Blog/update'); Route::delete('blogs/:id','index/Blog/delete'); ~~~ 也许你会想到使用路由分组功能来简化路由注册: ~~~ Route::group(['name'=>'blogs','prefix'=>'index/Blog'], function() { Route::get('/','index'); Route::get('create','create'); Route::post('/','save'); Route::get(':id','read'); Route::get(':id/edit','edit'); Route::put(':id','update'); Route::delete(':id','delete'); }); ~~~ 看起来是一个足够聪明的举动,但必须给每个操作方法注册路由规则的事实没有改变。 而如果使用资源路由的话,只需要使用一行代码就可以完成前面的RESTful路由规则注册: ~~~ Route::resource('blogs','index/Blog'); ~~~ 如果采用配置方式定义的话,使用下面的方式: ~~~ return [ // 定义资源路由 '__rest__' => [ 'blogs' => 'index/Blog', ], ]; ~~~ rescource方法给index模块的Blog控制器注册了一个名为blogs(这个名称其实是随意的)的资源路由,其实内部会自动注册前面我们注册的7个路由规则,没错,这一切都是自动完成的。资源路由会给规定的每个操作方法实际注册一个路由规则,并且可以定义每个方法的请求类型。 也可以在定义资源路由的时候限定执行的方法(标识),例如: ~~~ // 只允许index read edit update 四个操作 Route::resource('blogs','index/Blog',['only'=>['index','read','edit','update']]); // 排除index和delete操作 Route::resource('blogs','index/Blog',['except'=>['index','delete']]); ~~~ 注意这里的index、read、edit和update都是资源操作标识,并不是实际的操作方法。 #### 补充路由 如果需要对资源路由进行补充或者替换,可以在注册资源路由之后,进行补充注册: ~~~ // 注册资源路由 Route::resource('blog','index/Blog'); // 替换blog/:id 路由规则 Route::get('blog/:id','index/Test/read'); // 增加新的理由规则 Route::get('blog/:year/:month','index/Blog/archive'); ~~~ 如果在注册资源路由之前进行路由规则替换的话,可以配合only和except路由参数。 #### 资源嵌套 资源路由允许进行嵌套,表示对blogs资源下面的comment资源进行操作: ~~~ // 注册blogs.comment资源路由 Route::resource('blog.comments','index/Comment'); ~~~ 注册的comment控制器仍然是一个RESTful资源控制器,不过其方法的参数略有区别,以read和edit操作方法为例: ~~~ <?php namespace app\index\controller; class Comment { public function read($id,$blog_id) { } public function edit($id,$blog_id) { } } ~~~ 其实比之前的blog资源控制器的对应方法多了一个blog_id参数。 可以访问如下地址: ~~~ http://tp5.com/blog/128/comments/32 http://tp5.com/blog/128/comments/32/edit ~~~ 生成的路由规则分别是: ~~~ blog/:blog_id/comments/:id blog/:blog_id/comments/:id/edit ~~~ 也就是comment资源的上级资源ID,嵌套资源的资源ID默认规范是资源名_id,这里的上级资源的名称就是blog,我们可以更改资源ID的名称,例如: ~~~ // 注册blogs.comment资源路由 Route::resource('blog.comments','index/Comment',['var'=>['blog'=>'blogId']]); ~~~ Comment资源控制器的代码需要改为: ~~~ <?php namespace app\index\controller; class Comment { public function read($id,$blogId) { } public function edit($id,$blogId) { } } ~~~ 理论上,资源可以多级嵌套,这完全取决于你的应用场景。 小结 现在大家已经领略了资源路由的强大了,下一篇我会给大家讲解如何快速生成路由地址。