thinkphp 6 的 json() 方法自动设置响应头、安全序列化并处理模型字段逻辑;tp5.1 则需手动转数组或调用 tojson();手动 json_encode() 必须设头、防乱码、校验失败。

ThinkPHP 6 的 json() 方法直接返回 JSON 响应
如果你在控制器里处理完数据,想直接输出 JSON,别手动 json_encode() —— ThinkPHP 6 提供了原生支持的 json() 方法,它会自动设置 Content-Type: application/json 头,并对对象/数组做安全序列化(包括处理 DateTime、Collection、模型实例等)。
常见错误是先 json_encode($obj) 再用 return,结果响应头没设、中文乱码、时间字段变空——这些都由 json() 自动兜底。
- 模型对象(如
User::find(1))传给json()会自动调用其toArray(),并过滤隐藏字段($hidden)、追加属性($append) - 如果对象实现了
JsonSerializable接口,json()会优先调用它的jsonSerialize() - 不建议对模型对象先
toArray()再json(),多一次转换且可能绕过模型的序列化逻辑
ThinkPHP 5.1 中 json() 行为略有不同
TP5.1 的 json() 本质是封装了 json_encode(),但默认不处理对象——遇到非数组/标量类型(比如模型实例)会报错:Type error: json_encode() expects parameter 1 to be array, object given。
解决办法不是硬转数组,而是利用模型自带的 toArray() 或 toJson():
-
return json($user->toArray());—— 最常用,兼容字段隐藏、类型转换 -
return json($user->toJson());—— 返回字符串,需确保Content-Type正确(json()会自动设,放心用) - 若对象来自第三方类且没实现
JsonSerializable,必须先转成数组或手动定义toArray()方法
手动 json_encode() 时必须注意的三件事
真要自己调用 json_encode()(比如需要自定义选项),以下三点漏掉一个就容易出问题:
- 必须显式设置响应头:
header('Content-Type: application/json; charset=utf-8'); - 中文乱码?加
JSON_UNESCAPED_UNICODE选项:json_encode($data, JSON_UNESCAPED_UNICODE) - 时间对象、资源句柄、闭包会导致
json_encode()返回false,务必检查返回值:$json = json_encode($data); if ($json === false) { throw new Exception('JSON encode failed: ' . json_last_error_msg()); }
模型中控制 JSON 输出字段的两种方式
前端不需要全部字段,又不想在每个 json() 调用前手动 unset()?直接在模型里配置:
- 用
$hidden数组隐藏敏感字段:protected $hidden = ['password', 'token']; - 用
$visible显式声明只输出哪些字段(优先级高于$hidden):protected $visible = ['id', 'name', 'email']; - 注意:这些配置只对模型自身的
toArray()和toJson()生效;如果对象被嵌套在普通数组里,不会自动触发
with())和序列化选项的叠加,比如 toJson(JSON_PRETTY_PRINT) 会忽略模型里的 $hidden,这时候得回到 toArray() + json_encode() 组合。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











