商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > ThinkPHP模型字段类型转换如何处理JSON数据【模型】

ThinkPHP模型字段类型转换如何处理JSON数据【模型】

  发布于2026-07-05 阅读(0)

扫一扫,手机访问

ThinkPHP 里处理 JSON 字段,很多人都踩过同一个坑:明明配了类型转换,数据就是不对。要么读出来还是字符串,要么写入直接报错。这背后其实是一套非常严谨的规则——拆开来看反而简单。

JSON字段不自动转数组?必须同时配 $type$json

只写 $type = ['data' => 'json']$model->data 还是字符串;只写 $json = ['data'],写入时直接报 Array to string conversion。ThinkPHP 把读取解码和写入编码拆成两件事,缺一不可。

  • $type 控制读取时是否调用 json_decode()(但仅当 $json 也存在时才真正生效)
  • $json 控制写入前是否调用 json_encode(),且会反向触发读取解码逻辑
  • 字段名必须和数据库列名完全一致,大小写、下划线都不能错,比如数据库是 user_info,就不能写成 userInfo
  • TP6.0+ 支持 jsonb(PostgreSQL),MySQL 不认这个值,写错就等于没配

写入 JSON 字段时数组被双层编码?别手动 json_encode()

常见错误:赋值前自己 json_encode(['a'=>1]),再塞给 $model->data,结果 TP 再 encode 一次,存库变成 "{"a":1}" —— 典型的双重编码。

  • 正确做法:直接赋原生数组,$model->data = ['a' => 1]; $model->sa ve();,TP 在写入前自动 json_encode()
  • 批量赋值同理:$model->data(['data' => ['x' => 'y']])->sa ve();
  • 如果前端传的是 JSON 字符串(如 API 接口),先 json_decode($input['data'], true),再赋值,不能直接存字符串
  • 注意浮点数精度:PHP json_encode(3.141592653589793) 可能输出 3.1415926535898,这不是 TP 问题,是底层行为

修改 JSON 数组内部值不生效?必须整体重新赋值

$model->data['name'] = 'new'; $model->sa ve(); 不会更新数据库 —— ThinkPHP 不监听数组内部变化,只检测字段级是否被重新赋值。

  • 安全写法:$data = $model->data; $data['name'] = 'new'; $model->data = $data; $model->sa ve();
  • 更健壮的做法:先用 $model->getData('data') 拿原始字符串,json_decode() 后操作,避免 null 或非法 JSON 导致异常
  • 如果字段值为 null 或空字符串,$model->data 返回 null,不是空数组,需自行兜底:return $value ?: [];
  • toJson() 输出时 JSON 字段变回字符串?因为序列化走的是原始数据,不是 getAttr(),想保持结构得加到 $append 或重写 toArray()

数据库字段不是 JSON 类型?别硬配 json 类型

MySQL 的 VARCHARTEXT 字段里存了 {"a":1},配了 'data'=>'json' 看似能用,但一旦内容含非法 JSON(比如中文乱码、未转义引号),$model->data 就返回 null,且无提示。

  • 确认数据库字段类型:MySQL 5.7+ 建议用原生 JSON 类型,兼容性好、支持 whereJsonContains() 等查询
  • 非 JSON 类型字段(如逗号分隔字符串),不要配 json,改用访问器:getTagsAttr() 里做 explode()setTagsAttr() 里做 implode()
  • 字段名含点号(如 settings.theme)无法用 $json 声明,只能靠 getSettingsAttr() 手动处理
  • TP8 虽默认对 JSON 类型字段做 decode,但 getData() 或直接 __get 仍可能返回原始字符串,别依赖“默认”行为

字段名匹配、$type$json 缺一不可、数组内部修改必须整体赋值——这三处漏掉任何一点,JSON 字段就退化成普通字符串,而且不容易立刻发现。

ThinkPHP模型字段类型转换如何处理JSON数据【模型】

本文转载于:https://www.php.cn/faq/2737232.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注