thinkphp 6 中需通过设置 $convertname = true 或重写 getattribute 方法实现下划线字段到驼峰属性的映射;visible/hidden 应配置驼峰属性名,toarray()/json() 输出需统一处理字段风格,升级时注意 $convertname 默认值及钩子冲突。

ThinkPHP 6 的 __get 和 getAttribute 怎么联动字段映射
ThinkPHP 6 默认不会自动把数据库字段名转成驼峰(比如 user_name → userName),除非你显式开启或手动干预。核心在于模型的 getAttribute 方法是否被重写,以及 __get 是否走到了它身上。
默认情况下,$model->userName 会触发 __get,再调用 getAttribute('userName');但 getAttribute 内部默认只查原字段名(userName),不自动转下划线。所以直接访问驼峰属性会返回 null 或报错。
- 开启自动转换:在模型里加
protected $convertName = true;(TP6.1+ 支持) - 更稳妥的做法是重写
getAttribute,对传入的$name做一次Loader::parseName($name, 1, false)转成下划线格式再查 - 注意:
$convertName只影响读取,不影响写入($model->userName = 'x'仍会设到userName属性,而非user_name字段)
为什么 visible / hidden 不生效于自动映射字段
因为 visible 和 hidden 是作用在模型的「属性名」上,不是数据库字段名。如果你开了字段映射,但没同步维护 visible 列表里的驼峰名,就容易漏掉或误隐藏。
- 错误写法:
protected $hidden = ['user_name'];—— 这个字段名根本不存在于模型属性中 - 正确写法:
protected $hidden = ['userName'];(对应映射后的属性名) - 如果同时支持两种访问方式(
$model->user_name和$model->userName),得把两个都写进hidden,否则序列化时会重复出现
toArray() 和 json() 输出时字段名混乱怎么办
输出结果字段名取决于你是否启用了 typeCast、是否重写了 toArray、以及有没有在 output 中配置字段转换器。
- 最简方案:在模型里加
protected $type = ['user_name' => 'string'];,然后确保$hidden用驼峰名 - 若需统一输出为下划线风格,别依赖映射,改用
setAttr/getAttr钩子,在getAttr里对userName返回$this->data['user_name'] - 警惕
json_encode($model)直接调用 —— 它绕过toArray,可能暴露原始数据结构
TP6.0 升级到 TP6.1+ 后映射突然失效
TP6.1 引入了 $convertName 开关,默认为 false;而部分老项目靠重写 __get 实现映射,升级后可能因底层 getAttribute 行为变化导致冲突。
- 检查是否同时存在自定义
__get和$convertName = true—— 二者叠加可能导致重复转换(userName→user_name→username) - 确认
think\facade\Db的连接配置里没有'deploy' => 0类似旧版兼容开关,它会影响字段解析逻辑 - 调试技巧:在
getAttribute开头加trace(['name' => $name, 'data' => $this->data]);,看实际传入名和数据键是否匹配
字段映射不是开个开关就一劳永逸的事,真正麻烦的是读写一致性、序列化边界、还有升级时那些没写在文档里的行为偏移。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











