如何将数据库蛇形命名字段转为模型驼峰命名,自定义方法dump仍为蛇形
问题原因分析
- 首先你定义的方法名错误:你写的
getAttributes是复数,Laravel 单个属性取值调用的是单数的getAttribute($key)方法,你当前的写法根本没有覆盖到单个属性的取值逻辑 - 打印模型/集合时字段还是蛇形,是因为
dd()打印、模型转数组/JSON时调用的是toArray()方法,直接读取模型$attributes、$relations属性的原始键名,不会逐个调用getAttribute方法取值,仅重写单个取值逻辑无法改变批量输出的键名
解决方案
1. 修正基础属性读写逻辑
首先重写正确的getAttribute(取值)和setAttribute(赋值)方法,保证驼峰格式的属性读写正常:
use Illuminate\Support\Str; // 驼峰属性取值 public function getAttribute($key) { // 优先尝试蛇形键取值,兼容关联属性直接读取 return parent::getAttribute(Str::snake($key)) ?? parent::getAttribute($key); } // 驼峰属性赋值 public function setAttribute($key, $value) { return parent::setAttribute(Str::snake($key), $value); }
2. 重写toArray方法处理批量输出
这一步是解决打印、转数组/JSON时键名还是蛇形的核心逻辑:
public function toArray() { $originalArray = parent::toArray(); $camelCaseArray = []; foreach ($originalArray as $key => $value) { $camelKey = Str::camel($key); // 递归处理嵌套数组/关联模型的键名 $camelCaseArray[$camelKey] = is_array($value) ? array_map(fn ($item) => is_array($item) ? collect($item)->mapWithKeys(fn ($v, $k) => [Str::camel($k) => $v])->toArray() : $item, $value) : $value; } return $camelCaseArray; }
优化建议
如果有多个模型需要做蛇形转驼峰的处理,可以把上面三个方法封装到一个Trait中,需要用到的模型直接引入Trait即可,避免重复代码:
// 定义Trait trait CamelCaseAttributes { public function getAttribute($key) { return parent::getAttribute(Str::snake($key)) ?? parent::getAttribute($key); } public function setAttribute($key, $value) { return parent::setAttribute(Str::snake($key), $value); } public function toArray() { $originalArray = parent::toArray(); $camelCaseArray = []; foreach ($originalArray as $key => $value) { $camelKey = Str::camel($key); $camelCaseArray[$camelKey] = is_array($value) ? array_map(fn ($item) => is_array($item) ? collect($item)->mapWithKeys(fn ($v, $k) => [Str::camel($k) => $v])->toArray() : $item, $value) : $value; } return $camelCaseArray; } } // 模型中引入 class YourModel extends Model { use CamelCaseAttributes; }
内容的提问来源于stack exchange,提问作者temp_name
相关产品推荐
相关产品推荐

