路由模式

一般默认的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,
],
powered by GitbookEdit Time: 2023-04-08 10:28:32