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

hykeda1年前ThinkPHP1315

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

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

下面是一个前置行为的中间件 (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 事件的简单应用

一、序章ThinkPHP6的手册中关于【事件】章节的介绍都是直接文字说明,给出创建的类文件,并没有一个好的示例来进行补充说明。对于刚接触【事件】的同学在阅读理解上增加了一点点困难,本文就在此结合示例简...

关于thinkphp5.1中间件的使用

关于thinkphp5.1中间件的使用

在tp5.1开始,有了中间件的概念。 首先中间件主要用于拦截或过滤应用的HTTP请求,并进行必要的业务处理。 生成中间件: php thin...

最新阿里云OSS文件上传部署

1、前往阿里云github下载SDK包:https://github.com/aliyun/aliyun-oss-php-sdk/releases。 这里介绍源码部署:Source code下载下来...

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

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

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

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

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

thinkphp5 导入第三方类库和导入扩展类库细节

在用到tp5之后,很多东西都不太一样了。在此记录些小经验: 类库的导入,tp5有两种类库,分别为第三方类库和扩展类库 导入扩展类库,tp的手册中有示例代码: extend目录下面...

发表评论    

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