路由模式
一般默认的URL
地址显得有点长,每次在输入地址显得有点麻烦,所以这时候路由就可以让URL
更加简化。下面就来说说如何通过路由简化URL访问。
定义路由
要使用Route类注册路由必须首先在路由定义文件开头添加引用(后面不再重复说明)
use think\facade\Route;
在项目根目录里route\app.php
定义路由规则
// Route::rule('路由表达式', '路由地址', '请求类型');
Route::rule('hello', 'index/hello', 'get');
单应用模式定义好路由规则后URL访问
<!-- 域名/路由名 -->
http://www.tp.com/hello
如果多应用模式使用路由,那么就请在该应用目录下创建route
文件夹,然后再在route
目录下创建app.php
路由配置文件。
// get路由
Route::get('hello', 'index/hello');
多应用模式定义路由后URL访问
<!-- 域名/应用/路由名 -->
http://www.tp.com/index/hello
注意的是定义好路由后,原来的URL访问会自动失效
强制路由
如果开启强制路由,整个网站的URL访问都要定义路由,否则会提示非法请求
config\route.php
'url_route_must' => true
路由类型
类型 | 描述 | 快捷方法 |
---|---|---|
GET | GET请求 | get |
POST | POST请求 | post |
PUT | PUT请求 | put |
DELETE | DELETE请求 | delete |
PATCH | PATCH请求 | patch |
* | 任何请求类型 | any |
Route::快捷方法名('路由表达式', '路由地址');
Route::get('hello/:name','index/hello');
Route::post('hello','index/hello');
规则表达式
规则表达式通常包含静态规则和动态规则,以及两种规则的结合,例如下面都属于有效的规则表达式
// 静态地址路由
Route::get('hello', 'index/hello');
// 静态地址和动态地址结合
Route::get('hello/:id', 'index/hello');
// 静态地址和动态地址结合
Route::get('hello/:year/:month/:day', 'index/hello');
// 全动态地址
Route::get(':year/:month/:day', 'index/hello');
// 使用[]把路由规则中的变量包起来,就表示该变量为可选
Route::get('hello/[:id]', 'index/hello');
当访问上面定义路由时
<!-- 正确匹配的 -->
http://www.tp.com/hello
http://www.tp.com/hello/1
http://www.tp.com/hello/2022/3/7
http://www.tp.com/2022/3/7
http://www.tp.com/hello || http://www.tp.com/hello/22
完全匹配
规则默认检测时只是对URL从头开始匹配,如果需要完整匹配可以在规则后面加上$
符号
// 完整匹配的规则
Route::get('hello/:id$', 'index/hello');
当访问上面定义的路由时
http://tp.com/hello // 正确匹配
http://tp.com/hello/thinkphp // 正确匹配
http://tp.com/hello/thinkphp/val/value // 不会匹配
全局规则和局部规则
系统默认的变量规则设置是\w+,只会匹配字母、数字、中文和下划线字符,并不会匹配特殊符号以及其它字符,需要定义变量规则或者调整默认变量规则。
可以在路由配置文件中自定义
config\route.php
// 增加中划线字符的匹配
'default_route_pattern' => '[\w\-]+',
全局规则
设置全局变量规则,全部路由有效
// 支持批量添加
Route::pattern([
'name' => '\w+',
'id' => '\d+',
]);
局部规则
局部变量规则,仅在当前路由有效
// 定义GET请求路由规则 并设置name变量规则
Route::get('hello/:id', 'index/hello')->pattern(['id' => '[\d]+']);
定义闭包路由
还支持通过定义闭包为某些特殊的场景定义路由规则,而不需要执行控制器的操作方法了,例如:
Route::get('hello', function () {
return 'hello,world!';
});
路由参数
我们还可以约束路由规则的请求类型或者URL后缀之类的条件,例如:
// 检测是否get请求类型以及后缀为html
Route::rule('hello','index/hello')->method('get')->ext('html');
如果需要设置批量路由参数,可以使用option
方法
// 检测是否后缀为html以及检测是否https请求
Route::get('hello', 'index/hello')
->option([
'ext' => 'html',
'https' => true
]);
路由中间件
路由中间件则表示仅在路由匹配之后才会执行某个中间件,在路由定义中使用middleware方法定义
// 只对当前路由启用中间件
Route::get('hello','index/hello')->middleware(app\index\middleware\Auth::class);
中间件
由于文档使用的是多应用模式,配置文件:app\index\middleware\Auth.php
<?php
namespace app\index\middleware;
class Auth
{
/**
* 处理请求
*
* @param \think\Request $request
* @param \Closure $next
* @return Response
*/
public function handle($request, \Closure $next)
{
if(empty(session('LoginUser')))
{
// 如果条件成立,则重定向回首页
return redirect((string)url('/'));
}
// 返回Request对象
return $next($request);
}
}
如果需要定义多个中间件,使用数组方式
Route::rule('hello/:name','hello')
->middleware([\app\middleware\Auth::class,\app\middleware\Check::class]);
如果你需要某个路由中间件是全局执行的,不管路由是否匹配,可以在config/route.php
配置文件添加
'middleware' => [
app\middleware\Auth::class,
app\middleware\Check::class,
],