发布于2026-07-05 阅读(0)
扫一扫,手机访问
ThinkPHP 里处理 JSON 字段,很多人都踩过同一个坑:明明配了类型转换,数据就是不对。要么读出来还是字符串,要么写入直接报错。这背后其实是一套非常严谨的规则——拆开来看反而简单。
$type 和 $json只写 $type = ['data' => 'json'],$model->data 还是字符串;只写 $json = ['data'],写入时直接报 Array to string conversion。ThinkPHP 把读取解码和写入编码拆成两件事,缺一不可。
$type 控制读取时是否调用 json_decode()(但仅当 $json 也存在时才真正生效)$json 控制写入前是否调用 json_encode(),且会反向触发读取解码逻辑user_info,就不能写成 userInfojsonb(PostgreSQL),MySQL 不认这个值,写错就等于没配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_decode($input['data'], true),再赋值,不能直接存字符串json_encode(3.141592653589793) 可能输出 3.1415926535898,这不是 TP 问题,是底层行为$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 类型MySQL 的 VARCHAR 或 TEXT 字段里存了 {"a":1},配了 'data'=>'json' 看似能用,但一旦内容含非法 JSON(比如中文乱码、未转义引号),$model->data 就返回 null,且无提示。
JSON 类型,兼容性好、支持 whereJsonContains() 等查询json,改用访问器:getTagsAttr() 里做 explode(),setTagsAttr() 里做 implode()settings.theme)无法用 $json 声明,只能靠 getSettingsAttr() 手动处理getData() 或直接 __get 仍可能返回原始字符串,别依赖“默认”行为字段名匹配、$type 和 $json 缺一不可、数组内部修改必须整体赋值——这三处漏掉任何一点,JSON 字段就退化成普通字符串,而且不容易立刻发现。

售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8