文章转自:learnku.com/laravel/t/2…
php
简而言之,中间件在 laravel 中的做用就是过滤 HTTP 请求,根据不一样的请求来执行不一样的逻辑操做。laravel
命令行执行下面的简单命令,就能够轻松建立一个新的中间件web
php artisan make:middleware <MiddlewareName>
//MiddlewareName 就是你要建立的中间件的名字
复制代码
执行上面的命令,Laravel 会在 app/Http/Middleware
目录下自动建立一个只包含 handle
方法的中间件。api
<?php
namespace App\Http\Middleware;
use Closure;
class RedirectIfSuperAdmin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
}
复制代码
在中间件被调用的时候,handle
方法就会执行。这里须要注意的是 handle
方法默认有两个参数 $request
和 $next
。 $request
用来接受应用的请求组求, $next
将请求传递给应用程序。这两个参数是 handle
必不可少的!中间件也包括前置中间件和后置中间件。数组
“前置中间件” 顾名思义在将请求转发到应用程序以前处理一些逻辑。 另外一方面,在中间件以后,在应用程序处理了请求并生成响应以后运行。bash
前置中间件:app
<?php
namespace App\Http\Middleware;
use Closure;
class RedirectIfSuperAdmin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
//你的逻辑就在这里
return $next($request);
}
}
复制代码
后置中间件:函数
<?php
namespace App\Http\Middleware;
use Closure;
class RedirectIfSuperAdmin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
//你的逻辑就在这里 例如 重定向到 `/`
return $response;
}
}
复制代码
全局中间件针对命中应用程序的每一个请求运行。 Laravel 自带了大多数这些中间件例如 ValidatePostSize
, TrimStrings
,CheckForMaintenanceMode
等等.ui
路由中间件仅在它们所链接的路由上运行 例如 redirectIfAuthenticated
.this
建立的任何中间件都必须注册,由于这是 Laravel 知道存在的惟一方式。 要注册中间件,只需打开名为 kernel.php
的文件,该文件位于 Http 文件夹中,以下所示:
This file contains list of all registered middlewares that come with Laravel by default. it contains three major arrays which 此文件包含默认 Laravel 提供的全部已注册中间件的列表。 它包含三个主要的中间件组 $middleware
, $middlewareGroups
和 $routeMiddleware
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* 应用程序的全局HTTP中间件。
*
* 这些中间件在应用程序的每一个请求期间运行。
*
* @var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
];
/**
* 应用程序的路由中间件组.
*
* @var array
*/
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',
'bindings',
],
];
/**
* 应用程序的路由中间件.
*
* 能够将这些中间件分配给组或单独使用。
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
//the just created middlware
'superadmin' => \App\Http\Middleware\RedirectIfSuperAdmin::class,
];
}
复制代码
$middleware
数组包含全局中间件,它运行应用程序的每一个HTTP请求,因此若是你想为每一个请求运行一个中间件,你应该在这里注册它。 $middlewareGroups
使得能够在组中注册中间件,从而更容易经过使用组名将大量中间件附加到路由。 $routeMiddleware
数组包含各个注册的路由中间件。
有两个主要方法能够把注册好的中间件应用到路由中。
经过构造方法分配中间件
经过构造方法分配中间有很大的灵活性,它提供了两个重要的方法except($parameters)
和 only($parameters)
,这两个方法能够容许或阻止中间件应用到控制器中的辅助方法。不使用这两个方法,中间件将使用与控制器的每一个方法。
<?php
use Illuminate\Http\Request;
class ForumController extends Controller
{
public function __construct(){
/**in this case the middleware named auth is applied
to every single function within this controller
*/
$this->middleware('auth');
}
public function viewForum(){
return view('index');
}
public function edit($id){
}
public function delete($id){
}
}
复制代码
使用 except
和 only
方法咱们能够选择把中间件应用到指定方法。
<?php
use Illuminate\Http\Request;
class ForumController extends Controller
{
public function __construct(){
/**the authentication middleware here applies to all functions but
viewForums() and viewForumDetails() and the opposite of this happens
when you use only()
*/
$this->middleware('auth')->except(['viewForums', 'viewForumDetails']);
}
public function viewForums(){
return view('index');
}
public function edit($id){
}
public function delete($id){
}
public function viewForumDetails(){
}
}
复制代码
若是注册的中间件能够直接附加到路由,以下所示:
<?php
//方法 1
Route::get('admin/profile', function () {
//action
})->middleware('auth');
/**方法 2
或者像这样使用彻底限定的类名:
*/
use App\Http\Middleware\CheckAge;
Route::get('admin/profile', function () {
// action
})->middleware(CheckAge::class);
//方法 3
Route::group(['middleware' => ['web']], function () {
//action
});
复制代码
N:B 中间件组能够像单个中间件同样分配给路由
其余参数能够传递给中间件。 典型示例是将每一个用户ID分配给角色,中间件检查用户的角色以肯定是否有权访问所请求的 URI。 参数能够传递给中间件,以下所示:
<?php
//方法1 (Through route)
Route::get('admin/profile', function () {
//action
})->middleware('auth:<role>'); //<role> 这里应该被用户想要传递的任何参数替换。
//方法2 (Through a controller)
use Illuminate\Http\Request;
class ForumController extends Controller
{
public function __construct(){
$this->middleware('auth:<role>');
}
}
复制代码
经过用逗号分隔每一个参数,能够将多个参数传递给中间件。
<?php
Route::get('admin/profile', function () {
//action
})->middleware('auth:<role>,<age>,<country>'); //<role>, <age>, <country> 这里应该被用户想要传递的任何参数替换。
复制代码
这些参数在 $next
变量以后传递给中间件的 handle 函数
<?php
class RedirectIfSuperAdmin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next, $role, $age, $country)
{
//使用解析参数的中间件逻辑
return $next($request);
}
}
复制代码
要建立中间件,请执行如下过程
php artisan make:middleware 中间件名
.Laravel中间件能够更轻松地保护咱们的路由,过滤输入并完成许多其余工做,而无需编写如此多的逻辑。 查看官方 Laravel 文档 这里 了解中间件的更多功能,最重要的是练习。