thinkphp 的 saveall() 方法自动对模型 $json 属性定义的字段执行 json_encode,但须确保模型已声明 $json 数组、字段名一致、传入为数组而非 json 字符串,且需注意验证中断、浮点精度及整体更新限制。

ThinkPHP 的 saveAll() 方法在处理 JSON 类型字段时,会自动识别模型中定义的 $json 属性,并对指定字段执行 JSON 序列化(写入时调用 json_encode),无需手动编码。但前提是必须走模型逻辑,且数据格式正确。
确保模型已声明 $json 属性
这是关键前提。若没配置,saveAll() 会把数组当普通值处理,导致写入数据库的是字符串 "Array" 或直接报错。
- 在模型类中明确定义:
protected $json = ['config', 'extra', 'info']; - 字段名必须与数据库列名完全一致(区分大小写)
- 不支持点号嵌套(如
user.info),只认一级字段名
批量写入时传数组,别传 JSON 字符串
前端或业务层若已将 JSON 字符串传入,需先解码;否则会造成双重编码(如 {"a":1} → "{\"a\":1}")。
- ✅ 正确:
$dataList = [['name' => 'A', 'info' => ['email' => 'a@b.com']]]; - ❌ 错误:
'info' => '{"email":"a@b.com"}'—— 这会让 TP 再 encode 一次 - 若输入是字符串,先
json_decode($input['info'], true)再塞入数组
注意 saveAll() 不触发模型验证器默认行为
saveAll() 默认开启验证,但若某条数据校验失败,整个批次会中断返回 false。JSON 字段若含非法 UTF-8、资源类型或循环引用,json_encode 会静默失败或抛异常。
- 建议写入前统一校验:
is_array($item['info']) && json_encode($item['info'], JSON_THROW_ON_ERROR) !== false - 可临时关闭验证:
User::saveAll($dataList, ['validate' => false]) - 浮点数精度丢失属 PHP 原生行为,TP 不干预,业务层需自行 round 或转字符串保留
更新 JSON 字段要整体赋值
saveAll() 只检测字段是否被重新赋值,不监听数组内部变化。不能写 'info' => ['email' => 'x@y.com'] 后又试图改其中某个键再保存——必须一次性提供完整结构。
- 例如:想更新用户 info 中的 phone,得先读出原数组,修改后再整体写入
- 不支持类似
'info->phone' => '138xxx'的部分更新语法(那是查询用的) - 如需高频局部更新,建议改用
Db::table()->json()->update()配合JSON_SET原生函数
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











