thinkphp-路由的分组和miss、资源路由
路由分组
路由分组,即将相同前缀的路由合并分组,这样可以简化路由定义,提高匹配效率
使用group()方法,来进行分组路由的注册;
Route::group(function() {
Route::rule('ds/:id', 'Address/details');
Route::rule('rd/:name', 'Address/read');
})->ext('html');
好处就是可以对组内的路由统一调用链式方法,比如上面统一要求末尾必须带"html"
也可以省去第一参数,让分组路由更灵活一些;
// 第一个参数推荐使用控制器的名称 这个名称可以随意起
Route::group('address', function() {
Route::rule(':id', 'Address/details');
Route::rule(':name', 'Address/read');
})->ext('html')->pattern(['id' => '\d+', 'name' => '\w+']);
省略路由第一个参数后,我们就可以这么访问http://localhost/xuexi/tp6/public/address/1.html
但是这样就有一个问题,即无法自动匹配对应的控制器,所以这里才使用了正则,如果是id数值,那么就选择details这样。
使用prefix()方法,可以省略掉分组地址里的控制器(如果都一样的话 是可以这么操作的);
Route::group('address', function() {
Route::rule(':id', 'details');
Route::rule(':name', 'read');
})->ext('html')
->prefix('Address/')
->pattern(['id' => '\d+', 'name' => '\w+']);
使用append()方法,可以额外传入参数
Route::group('address', function() {
Route::rule(':id', 'details');
Route::rule(':name', 'read');
})->ext('html')
->prefix('Address/')
->pattern(['id' => '\d+', 'name' => '\w+'])
->append(['status' => 33]);
路由规则(主要是分组和域名路由)定义的文件,加载时会解析消耗较多的资源;尤其是规则特别庞大的时候(几百条),延迟解析开启让你只有在匹配的时候才会注册解析;我们在config/route.php 中开启延迟解析,多复制几组规则,然后来查看内存占用;
'url_lazy_route' => true, // 开启延迟解析,用到那个才加载哪个
MISS 路由
全局MISS,类似开启强制路由功能,匹配不到相应规则时自动跳转到MISS(匹配不到相对应的路由的时候不会出现报错页面了)。
Route::miss('public/miss');
这么写之后,还需要在controller/Error.php中,添加一个miss方法
class Error {
public function index() {
return '当前控制器不存在';
}
// 新添加的miss方法
public function miss()
{
return '404页面不存在';
}
}
分组MISS,可以在分组中使用miss 方法,当不满足匹配规则时跳转到这里;
在控制器中,先添加一个Miss方法
// 分组的404
public function miss()
{
return '404,miss';
}
在route/app.php中
Route::group('address', function() {
Route::rule(':id', 'details');
// 仅仅对此分组有效,当访问了address控制器中不存在的方法或者规则不匹配时候 会直接触发address的miss方法
Route::miss('miss');
})->ext('html')
->prefix('Address/')
->pattern(['id' => '\d+', 'name' => '\w+']);
比如正常访问是:http://localhost/xuexi/tp6/public/address/1.html
当访问http://localhost/xuexi/tp6/public/address/sad.html 时候,由于sad是一个字符串,不符合id的正则规则,所以会直接执行address中的miss方法。
注意,如果添加了ext规则,那么当访问http://localhost/xuexi/tp6/public/address/sad的时候,还是会之际报错,而不会进行miss方法。
资源路由
资源路由
资源就是资源类,资源控制器,这个类中全是增删改查一类的操作,新增和修改的表单页面也是在这里。这个类中全都是对数据库的一些操作。
资源路由,就是更加简化的形式来访问这些方法的路由。采用固定的常用方法来实现简化URL 的功能
Route::resource('ads', 'Address');
上门的路由就会执行简单访问address/index的方法
系统提供了一个命令,方便开发者快速生成一个资源控制器;在项目目录下
php think make:controller Blog
生成成功后,会生成controller/Blog.php这个文件
<?php
// 控制代码严格性 严格模式
declare (strict_types = 1);
namespace app\controller;
use think\Request;
class Blog
{
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
return '列表页';
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function create()
{
return '创建新增表单页';
}
/**
* 保存新建的资源
*
* @param \think\Request $request
* @return \think\Response
*/
public function save(Request $request)
{
return '新增页面';
}
/**
* 显示指定的资源
*
* @param int $id
* @return \think\Response
*/
public function read($id)
{
return '读取数据id' . $id;
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
return '修改表单页id' . $id;
}
/**
* 保存更新的资源
*
* @param \think\Request $request
* @param int $id
* @return \think\Response
*/
public function update(Request $request, $id)
{
return '修改id' . $id;
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
return '删除id ' . $id;
}
}
// 控制代码严格性 严格模式 php7.0加入
declare (strict_types = 1);
从生成的多个方法,包含了显示、增删改查等多个操作方法;
资源路由注册成功后,会自动提供以下方法,无须手动注册
GET 访问模式下:index(blog),create(blog/create),read(blog/:id)edit(blog/:id/edit)
POST 访问模式下:save(blog);
PUT 方式模式下:update(blog/:id);
DELETE 方式模式下:delete(blog/:id);
比如
/tp6/public/blog/4 自动会访问read方法
/tp6/public/blog/5/edit 自动访问edit方法 并传入id5
// 只要是post 那么默认就会执行save钩子
$.ajax({
type: 'POST',
data: {
id: 4,
type: 1
},
url: 'http://localhost/xuexi/tp6/public/blog',
success: function(res) {
console.log(res)
}
})
// 修改 执行update钩子 链接需要后面带上id
$.ajax({
type: 'PUT',
url: 'http://localhost/xuexi/tp6/public/blog/10',
success: function(res) {
console.log(res)
}
})
// 删除 执行delete钩子 链接需要后面带上id
$.ajax({
type: 'DELETE',
url: 'http://localhost/xuexi/tp6/public/blog/10',
success: function(res) {
console.log(res)
}
})
默认的参数采用id 名称,如果你想别的,比如:blog_id,则:
在route/app.php中
Route::resource('blog', 'Blog')->vars([
'blog' => 'blog_id'
]);
在新生成的controller/Blog.php中,以read钩子为例
public function read($blog_id)
{
return '读取数据id' . $blog_id;
}
如果不改为相应的,那么就会报错。
可以通过only()方法限定系统提供的资源方法,比如下例,只能使用Index和read钩子
Route::resource('blog', 'Blog')->only([
'index', 'read'
]);
还可以通过except()方法排除系统提供的资源方法,即列出的钩子不能用
Route::resource('blog', 'Blog')->except(['read','delete','update']);
使用rest()方法,更改系统给予的默认方法,参数1.请求方式;参数2.地址;参数3.操作 要执行的方法;
Route::rest('create', ['GET', '/:id/add', 'create']);
Route::resource('blog', 'Blog');
设置好后,地址栏输入:/tp6/public/blog/5/add,那么自动执行create钩子。
注意顺序,rest必须写在resource前面
即此功能可以改写系统默认的方法以及访问的路径。如果批量修改
//批量
Route::rest([
'save' => ['POST', '', 'store'],
'update' => ['PUT', '/:id', 'save'],
'delete' => ['DELETE', '/:id', 'destory'],
]);
使用嵌套资源路由,可以让上级资源对下级资源进行操作,创建Commit 资源
通常项目中,比如一篇博文可能下面会对应很多评论,而评论会有自己的id,同时也有从属于博文的Id,下面是一个评论的例子
id评论自己的Id | blog_id 博文章的id | content | something |
---|---|---|---|
1 | 17 | xx | ... |
首先创建controller/Commit.php:
<?php
namespace app\controller;
use think\Request;
class Commit
{
public function read($id, $blog_id)
{
return '评论的 id:'.$id.',从属的博文 id:'.$blog_id;
}
public function edit($id, $blog_id)
{
return '评论的 id:'.$id.',从属的博文 id:'.$blog_id;
}
}
然后在route/app.php中(固定写法)
Route::resource('blog', 'Blog');
Route::resource('blog.commit', 'Commit');
资源嵌套生成的路由规则如下:
http://localhost:8000/blog/:blog_id/comment/:id
http://localhost:8000/blog/:blog_id/comment/:id/edit
如此即可访问到commit控制器下对应的方法。
嵌套资源生成的上级资源默认id 为:blog_id,可以通过vars 更改;
Route::resource('blog.comment', 'Comment')
->vars(['blog'=>'blogid']);