深入解析Laravel的中间件
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 自带了大多数这些中间件例如ValidatePostSize
, TrimStrings
,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){ } }
使用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);
}
}
摘要
要创建中间件,请执行以下过程
- 使用 artisan 命令创建中间件 php artisan make:middleware 中间件名.
- 在 app→Http 文件夹中的 kernel.php 中注册中间件
- 在创建的中间件中编写逻辑
- 将中间件分配给路由或控制器
结论
Laravel 中间件可以更轻松地保护我们的路由,过滤输入并完成许多其他工作,而无需编写如此多的逻辑。 查看官方 Laravel 文档 这里 了解中间件的更多功能,最重要的是练习。
还有更多进阶学习资料可以免费领取进阶PHP月薪30k>>>架构师成长路线【视频、面试文档免费获取】
深入解析Laravel的中间件的更多相关文章
- laravel的中间件创建思路
网上有很多解析laravel中间件的实现原理,但是不知道有没有读者在读的时候不明白,作者是怎么想到要用array_reduce函数的? 本文从自己的角度出发,模拟了如果我是作者,我是怎么实现这个中间件 ...
- Laravel 使用中间件进行权限控制
Laravel 使用中间件进行权限控制 飞凡的陀螺 关注 2018.01.24 17:45 字数 264 阅读 1138评论 0喜欢 1 先看 文档Laravel 中间件提供了一种方便的机制来过滤进入 ...
- laravel StartSession中间件的实现原理
1. 打开app\Http\Kernel.php,找到StartSession的位置.这里要说一下,middleware中的中间件是都会被执行的,但执行的顺序我不知道,还需看源码来实现 protect ...
- Laravel之中间件
一.中间件的作用 HTTP 中间件提供了一个便利的机制来过滤进入应用的 HTTP 请求.例如,Laravel 包含了一个中间件来验证用户是否经过授权,如果用户没有经过授权,中间件会将用户重定向到登录页 ...
- laravel 加中间件的方法 防止直接打开后台
路由 routes.php Route::group(['middleware' => ['web','admin.login.login']], function () { //后台首页路由 ...
- 【原创】express3.4.8源码解析之路由中间件
前言 注意:旧文章转成markdown格式. 跟大家聊一个中间件,叫做路由中间件,它并非是connect中内置的中间件,而是在express中集成进去的. 显而易见,该中间件的用途就是 ------ ...
- Laravel 5 中间件、路由群组、子域名路由、 权限控制的基本使用方法
创建控制器: php artisan make:controller Admin/IndexController 创建Middleware: php artisan make:middleware T ...
- Laravel 利用中间件控制权限。
1.把所有需要控制的url写到config/admin.php里. 2.http/kernel.php文件里加上中间件. 3.http/Middleware/Permission.php 4.视图层
- laravel在中间件内生成的变量如何传到控制器
在中间件内获取到一个变量,如何返回到控制器中并使用这个变量! 做了个demo: // web.php Route::get('/check', 'CheckController@check')-> ...
随机推荐
- 【译】GraalVM—下一代JVM介绍
原标题:GraalVM – an introduction to the next level JVM 随着Red Hat宣布Quarkus作为- 为GraalVM和HotSpot量身定制的下一代Ku ...
- 从连接器组件看Tomcat的线程模型——NIO模式
Tomcat8之后,针对Http协议默认使用org.apache.coyote.http11.Http11NioProtocol,也就是NIO模式.通过之前的博客分析,我们知道Connector组件在 ...
- echarts 踩坑 : id必须不同
我们可能用react前端框架开发项目. 也就是组件化开发. 一个页面里可能有很多组件. 而echarts是寻找特定ID的DOM去渲染的. 也就是说,如果整个页面.包括所有页面组件,有id相同的DOM, ...
- Linux安装禅道项目管理软件
1.从官网上面下载禅道的rpm文件 #wget http://dl.cnezsoft.com/zentao/7.1/zentaopms-7.1.stable-1.noarch.rpm 2.用指令安装 ...
- NoSQL数据库-MongoDB 学习(一)
基本介绍 MongoDB 是为了快速开发互联网 Web 应用而设计的数据库系统 MongoDB 的设计目标是极简.灵活.作为 Web 应用栈的一部分 MongoDB 的数据模型是面向文档的,所谓文档是 ...
- FaaS 给前端带来了什么?
一.Serverless 与 FaaS Serverless 是一种云计算理念,即无服务器计算(Serverless Computing): Serverless suggests that the ...
- docker-compose安装zabbix
在网上的很多帖子,我亲自试过,多数不行,启动后zabbix_server是退出状态,所以觉得自己亲自写一篇帖子,以作记录 1.安装docker和docker-compose yum install - ...
- 深入浅出系列第一篇(设计模式之单一职责原则)——从纯小白到Java开发的坎坷经历
各位看官大大们,晚上好.好久不见,我想死你们了... 先说说写这个系列文章的背景: 工作了这么久了,每天都忙着写业务,好久没有好好静下心来好好总结总结了.正好这段时间公司组织设计模式的分享分,所以我才 ...
- MySQL乱码问题(为什么?追根溯源)
引言 定位:查询数据库得到的结果集乱码,client端向数据库插入数据乱码. 网上有不少帖子,手把手地教给我们如何去改这一问题.方案大多数如下: 方案中最多介绍的就是更改配置文件,win下my.ini ...
- SpringBoot学习之整合Druid的简单应用
一.Druid介绍 Druid简介 Druid是目前Java语言中最好的数据库连接池之一.结合了 C3P0.DBCP 等 DB 池的优点,同时加入了日志监控.Druid 是一个分布式的.支持实时多维 ...