可以将 Laravel 中间件比喻成机场的安检流程。
- 机场入口(请求进入):当你到达机场准备登机时,你首先会来到机场的入口。这个入口就像是 Laravel 应用程序接收到 HTTP 请求的地方。
- 安检流程(中间件处理):在进入机场候机区之前,你需要通过一系列的安检步骤。这些安检步骤就像是 Laravel 中间件。安检人员会检查你的身份证、机票,确保你有登机的资格(类似于身份验证中间件);他们还会检查你的行李,确保没有携带违禁物品(类似于数据过滤中间件)。如果在安检过程中发现问题,你可能会被拒绝进入候机区(类似于中间件返回重定向或错误响应)。
- 登机口(路由处理):只有通过了安检,你才能进入候机区,然后前往登机口登机。登机口就像是 Laravel 中的路由,只有通过了中间件的处理,请求才能到达路由进行处理。
- 飞机起飞(响应返回):当你登上飞机,飞机起飞,将你送往目的地。这就像是 Laravel 应用程序处理完请求后,将响应返回给客户端。
通过这个比喻,可以更好地理解 Laravel 中间件在请求处理过程中的作用。
在 Laravel 中,中间件是一种过滤 HTTP 请求的机制,它可以在请求到达路由之前或响应返回给客户端之前对请求进行预处理或后处理。中间件可以用于各种任务,如身份验证、日志记录、CORS 处理等。
可以使用 Artisan 命令来创建一个新的中间件。打开终端,进入 Laravel 项目的根目录,然后运行以下命令:
php artisan make:middleware CheckAge
这将在 app/Http/Middleware
目录下创建一个名为 CheckAge.php
的中间件文件。
打开 app/Http/Middleware/CheckAge.php
文件,其内容大致如下:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class CheckAge
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
if ($request->age < 18) {
return redirect('home');
}
return $next($request);
}
}
在 handle
方法中,我们检查请求中的 age
参数是否小于 18。如果是,则将用户重定向到 home
路由;否则,继续处理请求。
有三种方式可以注册中间件:全局中间件、路由中间件和组中间件。
要将中间件注册为全局中间件,需要在 app/Http/Kernel.php
文件的 $middleware
数组中添加中间件类:
protected $middleware = [
// 其他中间件...
\App\Http\Middleware\CheckAge::class,
];
这样,每个 HTTP 请求都会经过该中间件。
要将中间件注册为路由中间件,需要在 app/Http/Kernel.php
文件的 $routeMiddleware
数组中添加一个键值对:
protected $routeMiddleware = [
// 其他路由中间件...
'age' => \App\Http\Middleware\CheckAge::class,
];
然后在路由中使用该中间件:
Route::get('admin', function () {
//
})->middleware('age');
可以将多个中间件组合在一起,形成一个中间件组。在 app/Http/Kernel.php
文件的 $middlewareGroups
数组中定义组:
protected $middlewareGroups = [
'web' => [
// 其他中间件...
],
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'admin' => [
'age',
// 其他中间件...
],
];
然后在路由中使用该组:
Route::middleware('admin')->group(function () {
Route::get('dashboard', function () {
//
});
});