thinkphp字段映射需分层配置:field()用于sql查询别名,$mapping实现模型属性驼峰转换,append+getter控制序列化输出,$type与$json配合处理json字段,各层不可混用。

模型查出来的字段名和你代码里用的不一致?不是数据库没设好,而是你没配对映射方式——ThinkPHP 不会自动把 user_name 变成 userName,也不会把 created_at 自动转成 createdAt,得你自己选对方法。
field('原字段 AS 新字段') 是最直接的查询时重命名
适用于单次查询、临时改名、API 输出字段需兼容前端约定等场景。它不改模型逻辑,只改 SQL SELECT 子句输出的键名。
- 必须写
AS,不能只写'id user_id',否则解析失败,字段还是叫id - 双引号包裹可保小写(尤其在 MySQL 严格模式或某些驱动下):
'id AS "user_id"' - 多个字段用逗号分隔:
'id AS "uid", name AS "full_name", status AS "state"' - 注意别名不能含空格或非法字符,否则 PDO 报错
SQLSTATE[HY000]: General error
模型里配 $mapping 是全局字段名转换
适合整个模型统一风格,比如数据库用下划线,PHP 属性用驼峰;或对接遗留系统字段名不一致。
- ThinkPHP 6+ 支持
protected $mapping = ['user_name' => 'userName'];,但仅作用于模型读取后的属性赋值(即$user->userName可访问),不影响原始数组键名 - 该配置不会改变
$user->toArray()的输出,默认仍输出数据库字段名;要改输出,得配合$visible或append+ 手动 getter - 大小写敏感:
'User_Name'≠'user_name',数据库字段是啥,这里就得写啥 - 不支持嵌套映射(如
'profile.name'),只认一级字段
用 append + getter 实现运行时字段别名
当你需要“查出来就有新字段名”,且不想改 SQL 或影响原始数据结构时,这是最灵活的方式。
- 先定义 getter 方法,名字必须是
get + 别名 + Attr格式,例如:getOrderIdAttr()→ 对应字段order_id - 在模型中声明:
protected $append = ['order_id'];(注意:这里写的是别名,不是原字段) - getter 内部返回原字段值:
return $this->id;,这样$user->toArray()就会包含'order_id' => 123 - 如果同时想隐藏原字段,加
protected $hidden = ['id']; - ⚠️ 避免 getter 里做 DB 查询,否则 N+1;也别在 getter 里改
$this->attributes,会干扰脏数据检测
JSON 字段别名容易漏掉 $json 配置
很多人给 $type 加了 'data' => 'json',结果 $model->data 还是字符串——因为没配 $json,自动解码根本没开。
- 必须同时写:
protected $type = ['data' => 'json'];和protected $json = ['data']; -
$json是开关,$type是类型说明;缺一不可 - 写入时,ThinkPHP 不会自动
json_encode,你得传数组进去,框架才在入库前编码;如果传字符串,就原样存,不触发转换 - 别用
'array'替代'json',MySQL 原生 JSON 类型字段必须配'json'才能正确处理 null / bool / nested 结构
字段映射真正生效的前提,是你清楚当前处在哪一层:SQL 输出层(field)、模型属性层($mapping)、序列化输出层(append + hidden)、还是类型转换层($type + $json)。混用时最容易出现“写了却没反应”——比如在 field 里改了别名,又在 append 里重复定义同名字段,结果值被覆盖或报错。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











