thinkphp6 前置和后置中间件的区别以及特殊情况

hykeda2年前ThinkPHP2178

首先官方文档是这么描述的:

中间件是在请求具体的操作之前还是之后执行,完全取决于中间件的定义本身。

下面是一个前置行为的中间件 (Before命名是随意的):

<?php

namespace app\middleware;

class Before
{
    public function handle($request, \Closure $next)
    {
        // 添加中间件执行代码

        return $next($request);
    }
}

下面是一个后置行为的中间

<?php

namespace app\middleware;

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

        // 添加中间件执行代码

        return $response;
    }
}


首先区别是:在前置中间件中使用 $request->controller() 获取不到访问的控制器名,而在后置中间件中则可以正常获取到

在前置中间件打印 $request 发现是获取不到访问的控制器和方法名

另外的区别是执行的顺序,但是我在实际的使用中发现一个问题

<?php
declare (strict_types = 1);

namespace app\middleware;

use app\controller\Common;

class CheckIp extends Common
{
    /**
     * 处理请求
     *
     * @param \think\Request $request
     * @param \Closure       $next
     * @return Response
     */
    public function handle($request, \Closure $next)
    {

        // 添加中间件执行代码
        echo '中间件开始'.PHP_EOL;
        $response = $next($request);

        // 添加中间件执行代码

        echo '中间件结束'.PHP_EOL;

        return $response;

    }
}


按照官方文档这个是一个后置的中间件,我在控制器中调用:

public function rss(){
    echo '控制器执行的代码'.PHP_EOL;
    return arrayToJson('',false,'文章不存在');
}

输出的结果为:

中间件开始
控制器执行的代码
中间件结束
{"result":{"success":false,"info":"文章不存在"}}

这样的结果是正常的使用结果,后置方法中的中间件结束确实是在控制器执行完以后才被执行。没有问题。

但是如果我在控制器中注释掉return,这个时候后置就失去了效果。

public function rss(){
    echo '控制器执行的代码'.PHP_EOL;
    // return arrayToJson('',false,'文章不存在');
}

现在的输出结果是:

中间件结束 中间件开始 控制器执行的代码

这里的执行顺序就错误了。具体还不知道是什么原因,是先执行了结束,再执行开始,最后执行控制器。这里甚至连换行都没有了。

只要在控制器中 加入return,不管是return什么东西,执行顺序都能正常。

相关文章

phpExcel 官方停止更新,不支持php7.4以上版本,改用 phpspreadsheet

composer require phpoffice/phpspreadsheet安装后:按需要引入文件use PhpOffice\PhpSpreadsheet\Spre...

thinkphp5 报错级别设置,屏蔽警告

本着严谨的原则,5.0版本默认情况下会对任何错误(包括警告错误)抛出异常,如果不希望如此严谨的抛出异常,可以在应用公共函数文件中(common.php)或者配置文件中使用error_report...

thinkphp 行为Hook 使用说明

关于tp的钩子功能,梳理下: 添加行为标签位: tp默认在tags.php文件中已经添加了: return [ // 应用初始化...

在thinkphp6中使用依赖注入或容器来创建对象

很多时候,在自己的控制器中需要调用另一个控制器中的方法,但是没有直接的继承关系,比如两个控制器同时继承了一个common类。如果我们直接new一个控制器中的类,就会提示Too few&nbs...

Thinkphp5 记录点,注意点

json对象转成数组 先用$flag->getContent() $flag = json_decode($flag->getContent(),true); 控制器: 1、当控制器...

关于thinkphp5.1钩子和行为的个人理解和使用

关于thinkphp5.1钩子和行为的个人理解和使用

thinkphp5中的钩子和行为属于AOP编程思想,类似于AOP编程中的“切面”的概念,简单理解就是一个切入点,可以大大增加程序的耦合性。如何使用钩子和行为来开发:首先在项目中创建一个行为文件夹:1、...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。