thinkphp 6 的 json 响应逻辑集中在 think\response::send() 方法中,json() 仅构造 type 为 'json' 的 response 实例;真正编码由 send() 调用 json_encode($data, $options) 完成,tp6.0 默认未透传 $options,需 tp6.1+ 全局配置或手动处理。

直接看 think\Response 的 send() 方法就行
ThinkPHP 6 的 JSON 响应逻辑不在独立的“Json 类”里,而是收在 think\Response 的静态 send() 方法中——它统一处理所有响应类型,json() 只是构造一个 type 为 'json' 的 Response 实例,真正编码和输出发生在 send() 里。
关键点就两行:
一是根据 $type 查表设 Content-Type;
二是对 json 类型分支调用 json_encode($data, JSON_UNESCAPED_UNICODE)(TP6.0 默认没传标志,TP6.1+ 全局配置可覆盖)。
常见误读:以为 json() 函数里有 JSON 编码逻辑。其实它只是返回一个未发送的 Response 对象,send() 才是出口。
json() 助手函数到底干了啥
它本质是 think\Response::create($data, 'json', $code, $header, $options) 的快捷封装,参数最终都落到 Response 构造过程里:
-
$data被存进self::$data静态属性,等待send()时读取 -
$options(如JSON_UNESCAPED_UNICODE)被缓存到实例属性,但只在send()中的json分支生效 -
$header会被合并进响应头,但不会立即发送——send()前任何header()调用都可能触发 “headers already sent” 错误
所以你在控制器里写 return json($data)->header(['X-Trace' => '1']),header 是记住了,但真正发出要等框架走到 send() 阶段。
为什么改了 json_encode 选项没生效
因为 TP6.0 默认没把 $options 透传给 send() 的 json_encode() 调用——它硬编码用了 JSON_UNESCAPED_UNICODE(仅 TP6.1+ 支持通过 config/app.php 的 'json_encode' => [] 全局覆盖)。
你手动传 json($data, 200, [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),在 TP6.0 是无效的;必须自己调用 json_encode() + response()->contentType() 绕过。
容易踩的坑:
- 在中间件里对
Response对象调用getData()再json_encode()重包,结果二次编码(比如原数据已是字符串) - 以为
json($data)->options(...)存在——其实Response类没有这个方法,TP 也没提供运行时修改 encode 选项的入口 - 查源码只翻
helper.php里的json(),漏看了它背后Response::create()和send()的联动
调试时怎么确认 JSON 真正怎么编的
别依赖浏览器看响应体,直接在 send() 方法里加日志(或 Xdebug 断点):
if ($type === 'json') {
\think\facade\Log::info('json_encode input', ['data' => $data, 'options' => $options]);
$data = json_encode($data, $options); // 这里才是真实编码点
}
你会发现:
- 即使你传了
JSON_UNESCAPED_UNICODE,如果$options在create()阶段没被正确保存,这里还是用默认值 - 若
$data是对象且没实现JsonSerializable,json_encode()会静默返回null,响应变成空字符串 -
send()里对$data还有一次call_user_func_array(self::$tramsform, [$data])(注意变量名拼错为tramsform),若你全局设了自定义 transform,它会先执行
最稳的验证方式:关掉所有中间件,用 curl -v 看原始响应头和 body,比 IDE 调试更接近真实链路。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











