ThinkPHP模型字段类型转换和JSON序列化需显式配置:必须通过$tye声明字段类型,并对JSON字段额外配置$json才能触发编解码;仅设$type不设$json会导致写入失败。

ThinkPHP模型字段类型转换和JSON序列化不是自动发生的,必须靠显式配置才能生效。核心在于两件事:一是用 $type 告诉模型“这个字段该转成什么”,二是对JSON字段额外声明 $json 才能触发编解码逻辑。
字段类型转换必须手动配 $type
数据库字段类型(比如 DATETIME、TINYINT、JSON)不会被自动识别。哪怕你用的是 MySQL 5.7+ 的 JSON 字段,模型也默认当字符串处理。要启用转换,得在模型里写:
-
声明方式:
protected $type = ['create_time' => 'datetime', 'status' => 'boolean', 'score' => 'float']; -
字段名必须准确:键名是数据库列名,不能带表前缀,也不能用别名(如
user_name就写'user_name') -
类型值要合法:只能用 ThinkPHP 认可的标识,比如
'datetime'、'json'、'integer',写'int'或'array'无效 -
datetime 和 timestamp 区别明显:
'datetime'返回 Carbon 对象,支持->diffForHumans();'timestamp'返回整型秒级时间戳,适合做加减运算
JSON 字段必须同时配 $type 和 $json
只写 'data' => 'json' 在 $type 里还不够——读取时会自动 json_decode,但写入时模型不会自动 json_encode,直接赋数组会报错。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
-
缺一不可:既要
protected $type = ['data' => 'json'];,也要protected $json = ['data']; -
指定目标类型:加
protected $jsonType = ['data' => 'array'];,可选array/object/string -
赋值要干净:直接给数组,不要自己 encode ——
$model->data = ['a' => 1]; $model->save();即可;若写$model->data = json_encode([...]);,TP 会再 encode 一次,导致双重编码 -
注意 null 和非法 JSON:字段值为
null或空字符串时,$model->data得到的是null,不是空数组,业务层需自行判断补默认值
数组类字段慎用 serialize,优先用 json
如果数据库字段是 VARCHAR 或 TEXT,且存的是 PHP 序列化字符串(比如老系统遗留数据),才用 'config' => 'serialize'。但新项目强烈推荐用 JSON 字段 + 'json' 类型。
立即学习“PHP免费学习笔记(深入)”;
- 语义清晰:JSON 是标准格式,跨语言友好;serialize 是 PHP 特有,不安全也不便调试
-
类型安全:JSON 字段配合
$json可控性强;serialize 对非标内容(如资源、闭包)反序列化会失败 -
别混用:数据库字段是 JSON 类型,就别在
$type里写'field' => 'serialize',否则读取时unserialize()会因格式不符报错
反序列化回模型要用 instance(),不是 create()
从接口或缓存拿到 JSON 数据,想还原成可操作的模型对象,不能用 new User($data) 或 User::create($data),否则主键不标记为已存在,下次 save() 会当成新增插入。
-
已存在记录:用
User::instance($data),它设exists = true、填充主键、保留原始快照,适合更新场景 -
新增记录:可用
User::create($data),但注意字段类型仍依赖$type配置,否则字符串状态字段可能存成字符串而非布尔值 -
关联数据要手动挂载:JSON 里的
"user": {...}不会自动变成$model->user关联对象,得用$model->setRelation('user', User::instance($data['user'] ?? []))


















