Laravel中间件的创建使用及中间件参数定义

1、中间件简介
Laravel中可以把HTTP中间件看做“装饰器”,在请求到达最终动作之前对请求进行过滤和处理。

中间件在Laravel中有着广泛的应用,比如用户认证、日志、维护模式、开启Session、从Session中获取错误信息,以及上一篇教程中提到的CSRF验证,等等。

中间件类默认存放在app/Http/Middleware目录下。

2、中间件创建及其使用
我们在《HTTP路由实例教程(二)—— 路由命名和路由分组》一文已经演示了如何创建中间件以及中间件的基本使用。

自定义中间件类只需要定义一个handle方法即可,然后我们将主要业务逻辑定义在该方法中,如果我们想在请求处理前执行业务逻辑,则在$next闭包执行前执行业务逻辑操作:

<?php

namespace App\Http\Middleware;

use Closure;

class BeforeMiddleware
{
    public function handle($request, Closure $next)
    {
        // 执行业务逻辑操作

        return $next($request);
    }
}
如果想要在请求处理后执行中间件业务逻辑,则在$next闭包执行后执行操作:

<?php

namespace App\Http\Middleware;

use Closure;

class AfterMiddleware
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        // 执行动作

        return $response;
    }
}
我们处理的大部分操作都是第一种场景,即在请求处理前执行操作,比如用户认证、CSRF验证、维护模式等都是这样,但也有用到第二种场景的时候,比如StartSession中间件,该中间件在请求处理前后都有操作,其handle方法如下:

public function handle($request, Closure $next)
{
    $this->sessionHandled = true;

    //如果session驱动已配置,那么我们需要开启session以便为应用准备好数据
    //注意Laravel session并没有使用原生的PHP session相关方法,因为它们显得那样蹩脚
    if ($this->sessionConfigured()) {
        $session = $this->startSession($request);
        $request->setSession($session);
    }

    $response = $next($request);

    // 同样,如果session经过配置那么我们需要关闭session以便将session数据持久化到某些存储介质中
    // 我们还会添加session id到响应头cookie中
    if ($this->sessionConfigured()) {
        $this->storeCurrentUrl($request, $session);
        $this->collectGarbage($session);
        $this->addCookieToResponse($response, $session);
    }

    return $response;
}
此外,定义好中间件后,需要在app/Http/Kernel.php文件中注册该中间件,如果我们定义的中间件想要在全局有效,即每次请求都会调用,则将该中间件追加到$middleware属性数组;否则如果中间件只是在某些特定的路由中使用,则将其追加到$routeMiddleware属性数组,并在路由定义时使用middleware选项指定。关于这一点我们已经在路由分组中有所陈述,这里不再赘述。

3、中间件参数
除了请求实例$request和闭包$next之外,中间件还可以接收额外参数,我们还是以TestMiddleware为例,现在要求年龄在18岁以上的男性才能访问指定页面,handle方法定义如下:

public function handle($request, Closure $next, $gender)
{
    if($request->input('age')>=18 && $gender==$request->input('gender')){
        return $next($request);
    }else{
        return redirect()->route('refuse');
    }
}
对应的路由配置如下:

Route::group(['middleware'=>'test:male'],function(){
    Route::get('/write/laravelacademy',function(){
        //使用Test中间件
    });
    Route::get('/update/laravelacademy',function(){
        //使用Test中间件
    });
});

Route::get('/age/refuse',['as'=>'refuse',function(){
    return "18岁以上男子才能访问!";
}]);
4、定义可终止的中间件
可终止的中间件是指定义了terminate方法的中间件,terminate方法会在一次请求生命周期的末尾执行一些操作。比如StartSession中间件定义了该方法,在响应数据发送到浏览器之后将session数据保存起来。

可终止的中间件需要追加到app/Http/Kernel.php类的全局中间件列表即$middleware属性数组中。

调用中间件的terminate方法时,Laravel会从服务容器中取出新的中间件实例,所以如果想要调用handle方法和terminate方法时使用的是同一个中间件实例,需要使用singleton方法将该中间件注册到服务容器。

时间: 2024-11-05 14:54:21

Laravel中间件的创建使用及中间件参数定义的相关文章

Laravel Session保存机制和terminate中间件

在 Laravel 中可以使用 Session 的 get, put, pull, set, has, flash 等方法进行操作,如:Session::put(['domain'=>'tanteng.me', 'host'=>'aliyun']),就可以设置两个 session 值,看看 put 方法: 代码位于vendor/laravel/framework/src/Illuminate/Session/Store.phpPHP /**  * Put a key / value pair

使用 Laravel 和 Angular 创建一个单页的评论应用 【已翻译100%】

完整代码:https://github.com/scotch-io/laravel-angular-comment-app 目前,Laravel和Angular均已经成为了Web发展世界里非常著名的工具.Laravel以给PHP社区引入的伟大内容著称,Angular以其惊人的前端工具及简单著称.组合这两大框架似乎是合乎逻辑的下一步. 在我们的使用环境下,我们将使用Laravel作为后端的RESTful API,Angular作为前端,以创建一个简单的单页的评论应用. 下面是一个简单的例子,展示了

多线程-C#创建线程调用方法参数出错

问题描述 C#创建线程调用方法参数出错 我想创建几个线程来熟悉多线程的一些知识于是写了一个小程序 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Threading;namespace 多线程试验{ class Program { static void Main(string[] args) {

js动态创建的方法传递参数

问题描述 js动态创建的方法传递参数 用ajax获取了 json数据 存进数组 动态创建a标签 现在想点击a时 触发onclick事件时传递参数 但一直失败 无奈 想知道怎么才能把参数传递出去上代码: mdId_arr.push('<li><a href=""#"">'+info.lists[i]+'</a>'+ '<a href=""#"" data-icon=""

Laravel HTTP路由基本使用及路由参数

1.路由基本使用示例 1.1 默认示例 Laravel中所有路由定义在/app/Http/routes.php文件中,该文件默认定义了应用的首页路由: Route::get('/', function () {     return view('welcome'); }); 这段代码的意思是:当访问应用首页http://laravel.app:8000(使用Homestead虚拟机作为开发环境)的时候,返回/resources/views/welcome.blade.php视图中的内容并渲染到浏

Python中函数的参数定义和可变参数用法实例分析

  本文实例讲述了Python中函数的参数定义和可变参数用法.分享给大家供大家参考.具体如下: 刚学用Python的时候,特别是看一些库的源码时,经常会看到func(*args, **kwargs)这样的函数定义,这个*和**让人有点费解.其实只要把函数参数定义搞清楚了,就不难理解了. 先说说函数定义,我们都知道,下面的代码定义了一个函数funcA ? 1 2 def funcA(): pass 显然,函数funcA没有参数(同时啥也不干:D). 下面这个函数funcB就有两个参数了, ? 1

Python函数可变参数定义及其参数传递方式实例详解

  本文实例讲述了Python函数可变参数定义及其参数传递方式.分享给大家供大家参考.具体分析如下: python中 函数不定参数的定义形式如下: 1.func(*args) 传入的参数为以元组形式存在args中,如: ? 1 2 3 4 5 6 def func(*args): print args >>> func(1,2,3) (1, 2, 3) >>> func(*[1,2,3]) #这个方式可以直接将一个列表的所有元素当作不定参数 传入(1, 2, 3) 2.

JS中定义函数时的参数定义为undefined

问题描述 看到大牛们写的js源码,想拜读学习一下.var KISSY = (function (undefined) { var host = this, S, guid = 0, EMPTY = ''; S = { __BUILD_TIME: '20130701201313', ... }; // exports for nodejs if (S.Env.nodejs) { S.KISSY = S; module.exports = S; } return S;})();请看以上的代码,为什么

ice中间件 vxworks-能否将ICE中间件用在VxWorks操作系统上

问题描述 能否将ICE中间件用在VxWorks操作系统上 能否将ICE中间件用在VxWorks操作系统上?或者有没有ICE平台是否支持VxWorks?ZeroC公司的网站上没有明确说支持VxWorks.有成功应用经验的大神请介绍一下,谢谢 解决方案 同求.我最近也在做这方面的工作.希望有大拿能提供帮助.