ThinkPHP 3.2.3 的一个 Bug 和一个错误的设计

ThinkPHP 3.2.3 的 ajax_rerurn 这个 Hook 是有逻辑错误的……
源代码在这里:

    protected function ajaxReturn($data,$type='',$json_option=0) {
        if(empty($type)) $type  =   C('DEFAULT_AJAX_RETURN');
        switch (strtoupper($type)){
            case 'JSON' :
                // 返回JSON数据格式到客户端 包含状态信息
                header('Content-Type:application/json; charset=utf-8');
                exit(json_encode($data,$json_option));
            case 'XML'  :
                // 返回xml格式数据
                header('Content-Type:text/xml; charset=utf-8');
                exit(xml_encode($data));
            case 'JSONP':
                // 返回JSON数据格式到客户端 包含状态信息
                header('Content-Type:application/json; charset=utf-8');
                $handler  =   isset($_GET[C('VAR_JSONP_HANDLER')]) ? $_GET[C('VAR_JSONP_HANDLER')] : C('DEFAULT_JSONP_HANDLER');
                exit($handler.'('.json_encode($data,$json_option).');');  
            case 'EVAL' :
                // 返回可执行的js脚本
                header('Content-Type:text/html; charset=utf-8');
                exit($data);            
            default     :
                // 用于扩展其他返回格式数据
                Hook::listen('ajax_return',$data);
        }
    }

其中 C('DEFAULT_AJAX_RETURN') 获取到的配置默认是 json
很明显 Hook::listen('ajax_return',$data) 所在的位置,决定了它正常情况都不会被调用。
不管你将它改成 xmljsonp、还是 eval

于是为了使这个 Hook 生效,只能将 DEFAULT_AJAX_RETURN 这个配置改成 jsonxmljsonpeval 之外的任意字符串。。。比如我将它改成 'DEFAULT_AJAX_RETURN' => 'hook'

然后在创建文件:/Application/Admin/Conf/tags.php

<?php
return array(
    'ajax_return' => array('Admin\\Behaviors\\ajaxBehavior'),
);

再创建文件:/Application/Admin/Behaviors/ajaxBehavior.class.php

<?php
namespace Admin\Behaviors;

use Think\Behavior;

class ajaxBehavior extends Behavior
{
    function run(&$data)
    {
        if ($data['status']===0) {
            http_response_code(500);
        }
        header('Content-Type:application/json; charset=utf-8');
        exit(json_encode($data, JSON_UNESCAPED_UNICODE));
    }
}

我的目的是:Controller 内调用 $this->error('tmdphp') 的时候,响应的 HTTP 状态码变成 500。
这样客户端才会正确的执行 jQuery.ajaxerror 回调。

其实这也算另一个 Bug 吧,Think\Controller::error 然道不应该响应一个错误的 HTTP 状态码?

但是没办法,鉴于团队的平均水平,用 ThinkPHP 开发仍然是最佳选择。

等会去 Github 提交个 PR 看看会不会被采纳。。。

    原文作者:王道中强流
    原文地址: https://segmentfault.com/a/1190000005024988
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞