深入解析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')-> ...
随机推荐
- 题解 P1484 种树
题目 传送门 cyrcyr今天在种树,他在一条直线上挖了 n 个坑. 这n个坑都可以种树,但为了保证每一棵树都有充足的养料,cyrcyr不会在相邻的两个坑中种树. 而且由于cyrcyr的树种不够,他至 ...
- 一些matlb会用到的函数
matlab这种软件功能很强大,但是都不是常常会用到,尤其是像在学生中.每次用的时候总会把一些基本的函数忘记,还的去网上查.我之前在使用的时候也总结过,可惜在一次数据丢失中全没了(︶︹︺). 从现在开 ...
- AndroidStudio查找硬编码的String字符串
在Menu的“Analyze”中,选择“Run Inspection By Name”,然后输入“Hardcoded strings”,执行后,可以找到所有没有加入strings.xml的字符串. 按 ...
- 检查string是否有重复尝试用map
链接: 题意:输入一些单词,找出所有满足如下条件的单词:该单词不能通过字母重排,得到输入文本的另外一个单词.在判断是否满足条件时,字母不分大小写,但在输出时应保留输入的大小写,按字典序排列. 题解:先 ...
- android 文件读写权限的设定
读取本地文件的权限问题 2016年08月15日 21:41:30 阅读数:2520 在一个音乐app过程中需要读取手机本地内存卡中的音乐文件并可以播放,具体遇到的问题如下:工程没有错误,运行出现以下信 ...
- Spring Boot+Socket实现与html页面的长连接,客户端给服务器端发消息,服务器给客户端轮询发送消息,附案例源码
功能介绍 客户端给所有在线用户发送消息 客户端给指定在线用户发送消息 服务器给客户端发送消息(轮询方式) 项目搭建 项目结构图 pom.xml <?xml version="1.0&q ...
- java基础(11)--封装
一.java面向对象三大特别: 1.封装 2.继承 3.多态 二.封装的作用 1.属性私有化(private) 2.对外提供简单的入口 如公开的set()与get()方法,并且都不带static ...
- 离线安装paramiko
1. 利用yum下载paramiko依赖的rpm软件包 安装yum-utils yum -y install yum-utils yumdownloader python-setuptoolsyumd ...
- 萌新学渗透之Hack The Box_Beep
我将我的walkthrough过程用视频解说的形式记载 视频地址https://www.bilibili.com/video/BV1VT4y1j7dg 一是因为看我视频的后来者应该都是刚入门的新手,视 ...
- 什么是PHP 面向对象
PHP 面向对象 在面向对象的程序设计(英语:Object-oriented programming,缩写:OOP)中,对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象. 在现实 ...