
本文详解如何在 Laravel 中实现 JSON 请求数据、Eloquent 模型属性和数据库存储值三者间的精准格式转换(如小写 → 首字母大写 → 全大写),并推荐使用 Eloquent 属性封装(Attribute)作为核心方案。
本文详解如何在 laravel 中实现 json 请求数据、eloquent 模型属性和数据库存储值三者间的精准格式转换(如小写 → 首字母大写 → 全大写),并推荐使用 eloquent 属性封装(`attribute`)作为核心方案。
在构建 API 时,常需协调不同层级的数据表示规范:前端提交的 JSON 字段习惯小写(如 "test example"),业务逻辑中模型属性需语义化(如 "Test Example"),而数据库出于索引或兼容性考虑可能要求统一全大写(如 "TEST EXAMPLE")。这种多级转换不应散落在控制器中硬编码,而应由模型自身职责化、可复用地完成。
Laravel 9+ 推荐使用 Illuminate\Database\Eloquent\Casts\Attribute 实现双向自动转换。它替代了旧版 accessor/mutator 方法,语法更清晰,且天然支持类型安全与链式调用。
以下以 name 字段为例,展示完整实现:
// app/Models/Example.php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Support\Str;
class Example extends Model
{
protected $fillable = ['name'];
protected function name(): Attribute
{
return Attribute::make(
// 获取时:数据库值 → 模型属性值(全大写 → 首字母大写)
get: fn ($value) => Str::ucwords(Str::lower($value)),
// 设置时:模型属性值 → 数据库值(首字母大写 → 全大写),同时兼容 JSON 输入(小写 → 全大写)
set: fn ($value) => Str::upper((string) $value)
);
}
}
✅ 关键说明:
- set 闭包处理 所有来源的赋值:无论是 $model->name = 'test example'(JSON 解析后)、$model->fill(['name' => 'test example']),还是 Example::create(['name' => 'test example']),均会自动转为 'TEST EXAMPLE' 存入数据库;
- get 闭包确保从模型读取时始终返回标准化的展示格式('Test Example'),与数据库原始值解耦;
- Str::lower() 在 get 中前置,可避免因数据库异常存入混合大小写导致 ucwords() 失效,增强健壮性。
⚠️ 注意事项:
- 不要滥用 serialize() 或手动 json_encode():该方法仅控制模型序列化为 JSON 的输出格式(即 API 响应),不参与请求入参解析;
- Resource 类(如 ExampleResource)仅用于响应层转换,不可用于反向构造模型,切勿尝试 ExampleResource::fromRequest()——Laravel 无此机制;
- 若需对批量请求(如数组嵌套)做深度转换,请结合 Form Request Validation 预处理或自定义 Cast 类,而非在 Attribute 中处理复杂结构;
- 数据库字段类型建议使用 VARCHAR 并设置 COLLATE utf8mb4_unicode_ci,避免大小写敏感导致查询异常。
总结:Attribute 是 Laravel 官方推荐的、最简洁可靠的「模型 ↔ 数据库」格式桥接方案;而「JSON → 模型」的映射,本质由 Laravel 的自动填充($fillable + fill())和属性转换协同完成——你只需专注定义「值该如何流转」,框架负责执行。











