拦截器组件
几乎所有Web框架都有拦截器的概念,拦截器作用于一次HTTP请求响应的过程,在请求被控制器处理的前或后进行一些统一处理。Laravel中,拦截器被叫做“中间件(Middleware)”。
创建中间件
这里我们创建一个名字为CheckParam
的中间件。
php artisan make:middleware CheckParam
上述命令会将代码文件自动创建到app/Http/Middleware
下。
拦截处理
下面代码是一个简单的中间件例子,我们检查请求参数,如果有名为param
的参数且参数值为123
,则继续处理请求。否则将重定向。
<?php
namespace App\Http\Middleware;
use Closure;
class CheckParam
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$param = $request->input('param');
if ($param == '123') {
session()->put('checkParam', true);
return $next($request);
} else {
return redirect('/');
}
}
}
代码逻辑其实非常简单,主要注意$next($request)
这个调用,其实它就代表请求的后续处理,我们在其前或后编写代码,就能分别实现请求处理前后的拦截逻辑了。
注册中间件
注册中间件到控制器
public function __construct()
{
$this->middleware(CheckParam::class)->only('index');
}
我们可以将中间件注册到一个控制器或控制器的某个方法,在控制器的构造函数中,使用$this->middleware()
指定需要的控制器类就可以了。
如果只希望中间件指定到某个或某几个方法上,或只排除某个或某几个方法,可以使用only()
或except()
函数指定方法名。
注册中间件到路由或路由组
Route::get('/demo', 'DemoController@demo')->middleware(CheckParam::class);
我们可以直接将中间件注册到一个或一组路由,上述代码中,中间件CheckParam
对/demo
这个GET
请求生效。
Route::get('/demo', 'DemoController@demo')->middleware(CheckParam::class, CheckParam2::class);
如果有多个中间件,使用逗号分隔就行了。
注册中间件到全局
全局中间件定义在app/Http/Kernel.php
的$middleware
中,如果需要定义全局中间件,直接在其内容后添加就行了。
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
中间件别名
配置中间件时,如果直接写类名可能不太方便(因为需要使用using
引入命名空间,或使用很长的类全名),我们可以给中间件起一个别名,配置中间件时不需要写类名,写别名字符串即可。在app/Http/Kernel.php
文件中,可以找到$routeMiddleware
,其中可以定义中间件别名的键值对。
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
中间件组
多个中间件可以组成中间件组,并统一配置一个别名。在app/Http/Kernel.php
文件中,可以找到$middlewareGroups
,其中可以定义中间件组。
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];