深入解析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')-> ...
随机推荐
- 从Excel(CSV)文件导入数据到Oracle
步骤: 1.准备数据:在excel中构造出需要的数据2.将excel中的数据另存为文本文件(有制表符分隔的)3.将新保存到文本文件中的数据导入到pl*sql中在pl*sql中选择tools--text ...
- ResNeXt论文阅读笔记.md
目录 1. 提出背景 2. 核心思想 3. 论文核心 4. 分组卷积 5. 核心代码 论文: Aggregated Residual Transformations for Deep Neural N ...
- 动手实现一个简单的 rpc 框架到入门 grpc (下)
之前手动实现了一次简陋的 rpc 调用,为了简单使用了 json 编码信息,其实这是非常不可靠的,go 中 json 解析会有一些问题,比如整数会变成浮点数,而且 json 字符串比较占空间. gRP ...
- iOS倒计时button闪烁
v _button.titleLabel.text = [NSString stringWithFormat:@"%d后重发",t]; [_button setTitle:[NSS ...
- Python源码剖析|百度网盘免费下载|Python新手入门|Python新手学习资料
百度网盘免费下载:Python源码剖析|新手免费领取下载 提取码:g78z 目录 · · · · · · 第0章 Python源码剖析——编译Python0.1 Python总体架构0.2 Pyth ...
- 为什么学习vue?
公司要求学习uni-app,了解了一下这个uni-app uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.H5.以及各种小程序(微 ...
- 论文阅读 ORBSLAM3
这周末ORB-SLAM3出现了.先看了看论文.IMU部分没细看,后面补上. Abstract 视觉,视觉惯导,多地图SLAM系统 支持单目/立体/RGBD相机 支持pinhole/鱼眼相机 基于特征/ ...
- PHP 中的字符串变量
PHP 字符串变量 字符串变量用于存储并处理文本. PHP 中的字符串变量 字符串变量用于包含有字符的值. 在创建字符串之后,我们就可以对它进行操作了.您可以直接在函数中使用字符串,或者把它存储在变量 ...
- Python File next() 方法
概述 next() 方法在文件使用迭代器时会使用到,在循环中,next()方法会在每次循环中调用,该方法返回文件的下一行,如果到达结尾(EOF),则触发 StopIteration高佣联盟 www.c ...
- 使用pdf.js实现前端页面预览pdf文档,解决了跨域请求
pdf.js主要包含两个库文件,一个pdf.js和一个pdf.worker.js,,一个负责API解析,一个负责核心解析 官网地址:http://mozilla.github.io/pdf.js/ 下 ...