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)
所在的位置,决定了它正常情况都不会被调用。
不管你将它改成 xml
、jsonp
、还是 eval
。
于是为了使这个 Hook
生效,只能将 DEFAULT_AJAX_RETURN
这个配置改成 json
、xml
、jsonp
、eval
之外的任意字符串。。。比如我将它改成 '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.ajax
的 error
回调。
其实这也算另一个 Bug 吧,Think\Controller::error
然道不应该响应一个错误的 HTTP 状态码?
但是没办法,鉴于团队的平均水平,用 ThinkPHP
开发仍然是最佳选择。
等会去 Github 提交个 PR 看看会不会被采纳。。。