当前位置:  首页>> 技术小册>> Laravel(10.x)从入门到精通(三)

章节:中间件 - 定义中间件

在Laravel框架中,中间件(Middleware)提供了一种便捷的方式来过滤进入应用程序的HTTP请求以及响应的退出。它们是位于请求处理管道中的一层,可以执行诸如身份验证、日志记录、CORS(跨源资源共享)检查、速率限制等多种任务。通过中间件,我们可以优雅地处理请求和响应,而无需在每个路由或控制器中重复相同的逻辑。本章节将深入探讨如何在Laravel 10.x中定义和使用中间件。

一、中间件的基本概念

在Laravel中,中间件可以视为一个类,该类包含了一个或多个handle方法。handle方法接收两个参数:$request(请求实例)和$next(闭包)。$request用于访问请求信息,而$next则是一个必须被调用的闭包,以将请求传递给管道中的下一个中间件或路由/控制器。

中间件的作用流程可以概括为:当一个请求进入应用时,它首先通过一系列的中间件,这些中间件可以对请求进行加工处理;然后,请求才会到达路由或控制器。同样,当响应准备返回时,它也会通过相同的中间件序列(但方向相反),允许中间件在响应发送给客户端之前对其进行修改。

二、定义中间件

要在Laravel中定义中间件,你需要通过Artisan命令行工具创建一个新的中间件类,或者手动在app/Http/Middleware目录下创建一个类。

2.1 使用Artisan命令创建中间件

打开终端或命令提示符,导航到你的Laravel项目根目录,然后运行以下命令来创建一个新的中间件:

  1. php artisan make:middleware MyMiddleware

这里的MyMiddleware是你想要创建的中间件的名字。执行上述命令后,Laravel会在app/Http/Middleware目录下创建一个新的中间件类文件,文件名与类名相匹配(首字母大写,其余遵循StudlyCaps命名约定)。

2.2 手动创建中间件

如果你选择不使用Artisan命令,也可以直接在app/Http/Middleware目录下创建一个新的PHP类文件。例如,创建一个名为AgeMiddleware.php的文件,并添加以下内容作为示例:

  1. <?php
  2. namespace App\Http\Middleware;
  3. use Closure;
  4. class AgeMiddleware
  5. {
  6. /**
  7. * 处理传入的请求。
  8. *
  9. * @param \Illuminate\Http\Request $request
  10. * @param \Closure $next
  11. * @return mixed
  12. */
  13. public function handle($request, Closure $next)
  14. {
  15. // 假设我们要检查用户的年龄是否达到某个要求
  16. if ($request->user() && $request->user()->age >= 18) {
  17. return $next($request);
  18. }
  19. // 如果用户年龄不符合要求,重定向到首页
  20. return redirect('home');
  21. }
  22. }

在上面的例子中,AgeMiddleware中间件检查当前用户(如果存在)的年龄是否至少为18岁。如果条件满足,则通过调用$next($request)将请求传递给管道中的下一个中间件或路由/控制器。如果不满足条件,则重定向用户到首页。

三、注册中间件

定义中间件后,你需要将其注册到应用中,以便在请求处理管道中使用。中间件可以在全局、路由组或单个路由级别上注册。

3.1 全局中间件

要在全局范围内使用中间件,你可以将其添加到app/Http/Kernel.php文件中的$middleware属性数组中。这样,每个进入应用的HTTP请求都会通过该中间件。

  1. protected $middleware = [
  2. // 其他全局中间件
  3. \App\Http\Middleware\AgeMiddleware::class,
  4. ];

注意:由于全局中间件会在每个请求上运行,因此应谨慎使用,以避免不必要的性能开销。

3.2 路由中间件

更常见的做法是将中间件分配给特定的路由或路由组。首先,你需要在Kernel.php文件的$routeMiddleware属性中注册你的中间件,并给它一个短键名:

  1. protected $routeMiddleware = [
  2. // 其他路由中间件
  3. 'age' => \App\Http\Middleware\AgeMiddleware::class,
  4. ];

然后,你可以在路由定义中使用这个短键名来分配中间件:

  1. Route::get('/protected-page', function () {
  2. // 只有满足年龄条件的用户才能访问
  3. })->middleware('age');
  4. // 或者在路由组中应用
  5. Route::middleware(['age'])->group(function () {
  6. Route::get('/admin/dashboard', function () {
  7. // 仅管理员且年龄符合要求才能访问
  8. });
  9. });

四、中间件参数

Laravel允许你向中间件传递额外的参数。这些参数在定义中间件时通过闭包或类方法接收。这对于需要根据不同情况执行不同逻辑的中间件特别有用。

4.1 通过闭包传递参数

在注册路由中间件时,可以直接在调用middleware方法时传递参数:

  1. Route::get('/user/{id}/profile', function ($id) {
  2. //
  3. })->middleware('role:editor');

为了处理这种带参数的中间件,你需要在中间件的handle方法中稍作修改,以接收这些参数:

  1. public function handle($request, Closure $next, $role)
  2. {
  3. if (! $request->user()->hasRole($role)) {
  4. // 权限不足处理
  5. }
  6. return $next($request);
  7. }

然而,Laravel的路由中间件默认不支持直接传递参数。上述示例主要是为了说明概念,实际实现时你可能需要自定义一个服务提供者来解析这些参数,或者使用其他方法(如查询字符串、路由参数等)间接传递。

4.2 类方法接收参数

另一种方法是让中间件类包含多个方法,每个方法处理不同的逻辑,然后在路由定义中通过指定方法来间接传递“参数”。

五、总结

在Laravel中,中间件是一个强大的功能,允许你在请求处理管道中插入自定义逻辑。通过定义中间件,你可以轻松地实现身份验证、日志记录、CORS检查等功能,而无需在每个路由或控制器中重复相同的代码。本章节介绍了如何定义中间件、注册中间件以及在中间件中传递参数的基本方法。希望这些内容能帮助你更好地理解和使用Laravel的中间件功能。


该分类下的相关小册推荐: