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

hykeda2年前ThinkPHP2145

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

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

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

相关文章

thinkphp6 使用中的注意点

thinkphp6 使用中的注意点

1、TP6中采用多应用模式需要安装  composer require topthink/think-multi-app如果需要使用view,还必须安装模板引擎...

composer安装插件包的时候提示PHP 版本不匹配

因为安装的 PHP 是 8.0 ,不匹配 composer.json 要求的版本,所以使用 composer 进行安装时会报错。在安装命令后加上 --ignore-pla...

Thinkphp6 中上传文件,验证文件大小及后缀名官方文档错误修改

Thinkphp6 中上传文件,验证文件大小及后缀名官方文档错误修改

官方文档示例:上传验证支持使用验证类对上传文件的验证,包括文件大小、文件类型和后缀:public function upload(){    // 获取表单上传文件 &nb...

composer升级thinkphp版本

之前用的thinkphp版本为tp5.0.12,最近tp已经更新到5.0.19以及5.1版本的5.1.12。 我一开始在目录下面直接使用了composer update...

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

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

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

发表评论    

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