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

hykeda2年前ThinkPHP1966

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

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

下面是一个前置行为的中间件 (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什么东西,执行顺序都能正常。

相关文章

thinkphp 行为Hook 使用说明

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

Thinkphp5 创建模块

一、创建三个模块 Common(公共模块),Index(前台模块),Admin(后台模块)。 index.php实际配置 <?php // 定义应用目录 define('APP_...

关于thinkphp6 where以数组形式查询,其中有or,and的处理

最近在写tp6的查询语句时,如果查询条件以数组形式传入,比如:$where[] = ['id','=',$id]; $where[] =...

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

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

发表评论    

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