发布于2026-07-06 阅读(0)
扫一扫,手机访问
在实际开发中,我们常常遇到这样的场景:用ThinkPHP返回JSON数据,结果出来的是紧凑的一行,中文还被转义了。这多半是因为没有正确配置JSON格式化器。这篇文章就来梳理一下,如何让ThinkPHP输出带缩进、中文不转义的可读JSON。

下面给出几种常用方案,从最简单的内置函数到自定义类、中间件,再到服务端层面的处理,按需选用即可。
ThinkPHP 6 的 json() 助手函数默认已经开启了 JSON_UNESCAPED_UNICODE 和 JSON_UNESCAPED_SLASHES,但缩进格式不会自动加——你需要显式传入 JSON_PRETTY_PRINT。
具体操作很简单:
$data = ['code' => 0, 'message' => 'SUCCESS', 'data' => ['user_id' => 100, 'name' => '张三']];return json($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);这行代码会自动设置 Content-Type: application/json; charset=utf-8,并输出带缩进和换行的格式化JSON。不过需要留意:JSON_PRETTY_PRINT 只在 PHP 5.4+ 里有效,而且会增加响应体大小,生产环境建议关掉。
如果全站API都要统一格式,可以写一个自定义的响应类,封装格式化逻辑。比如在 app/common/formatter/JsonFormatter.php 里创建一个类,继承 think\Response,然后重写 output() 方法,对原始数据调用 json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)。
写好后在 config/app.php 中配置 'response' => \app\common\formatter\JsonFormatter::class; 即可。关键点在于必须保证该类继承自 think\Response 并正确复写 send() 流程,否则 header 设置可能被跳过。
这个方法适合那些旧项目,控制器逻辑不方便修改。写一个中间件,在响应发出前捕获已生成的JSON字符串,然后重新格式化。
app/middleware/JsonPrettyMiddleware.phphandle() 方法里判断响应类型是否为 application/jsonjson_decode($content, true) 解析,再 json_encode(..., JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)$response->content($formattedJson)->header('Content-Length', strlen($formattedJson))警告:此方式必须确保响应尚未发送(即还没触发 send()),否则会报 Cannot modify header information 错误。
如果只是开发阶段想看看美化后的JSON,又不想影响正式响应,可以利用ThinkPHP调试模式的Trace面板。在 config/trace.php 里添加自定义面板,写一个trace插件类,在 onEnd 钩子中检测当前请求是否为JSON接口,若是,就把原始响应数据解析后生成HTML格式化预览块(不替换原响应)。这样既不影响前端解析,又能方便调试。
最后一种思路是在Web服务器层面做美化,完全不需要改PHP代码。适合运维统一管控的场景,但一般只建议在低QPS调试环境用。
mod_substitute 模块,配置基础缩进规则(如 Substitute "s/{/ {\n/g")ngx_http_sub_module 配合正则匹配JSON开头插入换行和缩进cjson.pretty.encode() 进行标准格式化需要提醒的是:服务端过滤会增加CPU开销,而且大体积JSON容易超内存限制,生产环境慎用。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8