一、什么是中间件?
当客户端发送请求至服务器时,HTTP请求会经过多个中间件,最后返回响应给客户端。中间件可以
-
在请求到达目标控制器或动作之前对请求进行操作
-
可以在响应离开目标控制器或动作之前对响应进行操作
二、中间件的作用
我们可以在不修改应用程序逻辑的情况下添加额外的功能,如
-
登录验证、
-
检查用户权限、权限控制
-
请求过滤
-
判断当前浏览器环境是在微信或支付宝
-
写系统日志
-
统计
三、中间件的类型
1、前置中间件
前置中间件的意思就是,在http请求完成之前,先执行中间件的代码。
一般用来检查用户权限
在app/middleware中新建中间件,每个中间件一个文件
<?php
namespace app\middleware;
// 前置行为的中间件
class AuthMiddleware
{
public function handle($request, \Closure $next)
{
// 添加中间件执行代码 start
echo ' </br>hello </br>';
// 添加中间件执行代码 end
return $next($request);
}
}
2、后置中间件
后置中间件的意思就是,在http请求完成之后,才开始执行中间件的代码。
一般用来写日志、统计
<?php
namespace app\middleware;
// 后置行为的中间件
class LogMiddleware
{
public function handle($request, \Closure $next)
{
$response = $next($request);
// 添加中间件执行代码 start
echo ' </br>good bye!</br>';
// 添加中间件执行代码 end
return $response;
}
}
中间件说明:
1、中间件的入口执行方法必须是handle
方法,而且第一个参数是Request
对象,第二个参数是一个闭包;
2、中间件handle
方法的返回值必须是一个Response
对象;
3、中间件里可以直接使用Request对象,获取请求参数;
四、使用中间件
根据作用范围可以分为4种中间件
全局中间件->应用中间件->路由中间件->控制器中间件
-
全局中间件
全局中间件在app
目录下面middleware.php
文件中定义
2. 应用中间件
直接在应用目录下面增加middleware.php
文件,定义方式和全局中间件定义一样,只是只会在该应用下面生效。
<?php
return [
app\middleware\AuthMiddleware::class,
];
访问该应用下的任何一个函数,都会先执行了中间件
3. 路由中间件
访问了对应的路由,则会调用对应的中间件,可以调用多个
Route::rule('hello/:name','hello')
->middleware([\app\middleware\Auth::class, \app\middleware\Check::class]);
4. 控制器中间件
在控制器中定义middleware
属性,例如:
上述代码指定了该控制器下的所有函数被调用都会执行对应的控制器
可以通过“except"和‘only’字段为控制器中函数自定义调用的中间件
<?php
namespace app\addons\controller;
use think\Controller;
class Index extends Controller{
// auth中间件,使用了except,表示出了hello方法外,这个控制器其他的方法都会执行这个中间件
// check中间件,使用了only表示只有这个控制器的login方法执行这个中间件
// log中间件,没有使用任何限定参数,表示这个控制器里面所有的方法都会执行log这个中间件
protected $middleware = [
'auth' => ['except' => ['hello']],
'check' => ['only' => 'login'],
'log'
];
public function index(){
echo "this is a addons index controller index function";
}
public function login(){
echo "abcd";
}
public function hello(){
echo "abcd";
}
}
五、向中间件传参
可以使用第三个参数传入额外的参数。
<?php
namespace app\middleware;
class Check
{
public function handle($request, \Closure $next, $name)
{
if ($name == 'think') {
return redirect('index/think');
}
return $next($request);
}
}
下面是给auth中间件传入了一个参数的值'admin'
Route::rule('hello/:name','hello')
->middleware('auth', 'admin')
->middleware('hello', 'thinkphp');
六、中间件向控制器传参
<?php
namespace app\middleware;
class Hello
{
public function handle($request, \Closure $next)
{
$request->hello = 'ThinkPHP';
return $next($request);
}
}
在控制器的方法里面可以直接使用
public function index(Request $request)
{
return $request->hello; // ThinkPHP
}
参考:
https://www.php.cn/faq/559015.html
https://www.php.cn/faq/591280.html
https://www.php.cn/faq/562939.html
https://www.kancloud.cn/manual/thinkphp6_0/1037493
https://www.gxlsystem.com/phpkuangjia-2336420.html
软件工程小施同学
20230909