Laravel 中间件是什么?

简而言之,中间件在 laravel 中的作用就是过滤 HTTP 请求,根据不同的请求来执行不同的逻辑操作。

我们可以通过中间件实现以下功能:

  • 指定某些路由
  • 设置 HTTP 响应头
  • 记录请求
  • 过滤请求的参数
  • 决定是否启用站点维护模式
  • 响应前后做一些必要的操作

自定义中间件

命令行执行下面的简单命令,就可以轻松创建一个新的中间件

php artisan make:middleware <MiddlewareName>
//MiddlewareName 就是你要创建的中间件的名字

执行上面的命令,Laravel 会在app/Http/Middleware目录下自动创建一个只包含handle方法的中间件。

<?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必不可少的!中间件也包括前置中间件和后置中间件。

“前置中间件” 顾名思义在将请求转发到应用程序之前处理一些逻辑。 另一方面,在中间件之后,在应用程序处理了请求并生成响应之后运行。

前置中间件:

<?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 自带了大多数这些中间件例如ValidatePostSizeTrimStrings,CheckForMaintenanceMode等等.

路由中间件仅在它们所连接的路由上运行
例如redirectIfAuthenticated.

注册中间件

创建的任何中间件都必须注册,因为这是 Laravel 知道存在的唯一方式。 要注册中间件,只需打开名为kernel.php的文件,该文件位于 Http 文件夹中,如下所示:

此文件包含默认 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){ } }

使用exceptonly方法我们可以选择把中间件应用到指定方法。如下所示:

<?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);
}
}

摘要

要创建中间件,请执行以下过程

  • 使用 artisan 命令创建中间件 php artisan make:middleware 中间件名.
  • 在 app→Http 文件夹中的 kernel.php 中注册中间件
  • 在创建的中间件中编写逻辑
  • 将中间件分配给路由或控制器

结论

Laravel 中间件可以更轻松地保护我们的路由,过滤输入并完成许多其他工作,而无需编写如此多的逻辑。 查看官方 Laravel 文档 这里 了解中间件的更多功能,最重要的是练习。


深入解析Laravel的中间件的更多相关文章

  1. laravel的中间件创建思路

    网上有很多解析laravel中间件的实现原理,但是不知道有没有读者在读的时候不明白,作者是怎么想到要用array_reduce函数的? 本文从自己的角度出发,模拟了如果我是作者,我是怎么实现这个中间件 ...

  2. Laravel 使用中间件进行权限控制

    Laravel 使用中间件进行权限控制 飞凡的陀螺 关注 2018.01.24 17:45 字数 264 阅读 1138评论 0喜欢 1 先看 文档Laravel 中间件提供了一种方便的机制来过滤进入 ...

  3. laravel StartSession中间件的实现原理

    1. 打开app\Http\Kernel.php,找到StartSession的位置.这里要说一下,middleware中的中间件是都会被执行的,但执行的顺序我不知道,还需看源码来实现 protect ...

  4. Laravel之中间件

    一.中间件的作用 HTTP 中间件提供了一个便利的机制来过滤进入应用的 HTTP 请求.例如,Laravel 包含了一个中间件来验证用户是否经过授权,如果用户没有经过授权,中间件会将用户重定向到登录页 ...

  5. laravel 加中间件的方法 防止直接打开后台

    路由 routes.php Route::group(['middleware' => ['web','admin.login.login']], function () { //后台首页路由 ...

  6. 【原创】express3.4.8源码解析之路由中间件

    前言 注意:旧文章转成markdown格式. 跟大家聊一个中间件,叫做路由中间件,它并非是connect中内置的中间件,而是在express中集成进去的. 显而易见,该中间件的用途就是 ------ ...

  7. Laravel 5 中间件、路由群组、子域名路由、 权限控制的基本使用方法

    创建控制器: php artisan make:controller Admin/IndexController 创建Middleware: php artisan make:middleware T ...

  8. Laravel 利用中间件控制权限。

    1.把所有需要控制的url写到config/admin.php里. 2.http/kernel.php文件里加上中间件. 3.http/Middleware/Permission.php 4.视图层

  9. laravel在中间件内生成的变量如何传到控制器

    在中间件内获取到一个变量,如何返回到控制器中并使用这个变量! 做了个demo: // web.php Route::get('/check', 'CheckController@check')-> ...

随机推荐

  1. 【译】GraalVM—下一代JVM介绍

    原标题:GraalVM – an introduction to the next level JVM 随着Red Hat宣布Quarkus作为- 为GraalVM和HotSpot量身定制的下一代Ku ...

  2. 从连接器组件看Tomcat的线程模型——NIO模式

    Tomcat8之后,针对Http协议默认使用org.apache.coyote.http11.Http11NioProtocol,也就是NIO模式.通过之前的博客分析,我们知道Connector组件在 ...

  3. echarts 踩坑 : id必须不同

    我们可能用react前端框架开发项目. 也就是组件化开发. 一个页面里可能有很多组件. 而echarts是寻找特定ID的DOM去渲染的. 也就是说,如果整个页面.包括所有页面组件,有id相同的DOM, ...

  4. Linux安装禅道项目管理软件

    1.从官网上面下载禅道的rpm文件 #wget http://dl.cnezsoft.com/zentao/7.1/zentaopms-7.1.stable-1.noarch.rpm 2.用指令安装 ...

  5. NoSQL数据库-MongoDB 学习(一)

    基本介绍 MongoDB 是为了快速开发互联网 Web 应用而设计的数据库系统 MongoDB 的设计目标是极简.灵活.作为 Web 应用栈的一部分 MongoDB 的数据模型是面向文档的,所谓文档是 ...

  6. FaaS 给前端带来了什么?

    一.Serverless 与 FaaS Serverless 是一种云计算理念,即无服务器计算(Serverless Computing): Serverless suggests that the ...

  7. docker-compose安装zabbix

    在网上的很多帖子,我亲自试过,多数不行,启动后zabbix_server是退出状态,所以觉得自己亲自写一篇帖子,以作记录 1.安装docker和docker-compose yum install - ...

  8. 深入浅出系列第一篇(设计模式之单一职责原则)——从纯小白到Java开发的坎坷经历

    各位看官大大们,晚上好.好久不见,我想死你们了... 先说说写这个系列文章的背景: 工作了这么久了,每天都忙着写业务,好久没有好好静下心来好好总结总结了.正好这段时间公司组织设计模式的分享分,所以我才 ...

  9. MySQL乱码问题(为什么?追根溯源)

    引言 定位:查询数据库得到的结果集乱码,client端向数据库插入数据乱码. 网上有不少帖子,手把手地教给我们如何去改这一问题.方案大多数如下: 方案中最多介绍的就是更改配置文件,win下my.ini ...

  10. SpringBoot学习之整合Druid的简单应用

    一.Druid介绍 Druid简介 Druid是目前Java语言中最好的数据库连接池之一.结合了 C3P0.DBCP 等 DB 池的优点,同时加入了日志监控.Druid 是一个分布式的.支持实时多维 ...