当前位置:首页 > CMS教程 > 其它CMS > 列表

Laravel 数据模型中 JSON、模型属性与数据库字段的多级格式转换实践

发布:smiling 来源: PHP粉丝网  添加日期:2026-07-05 18:40:48 浏览: 评论:0 

本文详解如何在 laravel 中实现 json 请求数据、eloquent 模型属性和数据库存储值三者间的精准格式转换(如小写 → 首字母大写 → 全大写),并推荐使用 eloquent 属性封装(`attribute`)作为核心方案。

在构建 API 时,常需协调不同层级的数据表示规范:前端提交的 JSON 字段习惯小写(如 "test example"),业务逻辑中模型属性需语义化(如 "Test Example"),而数据库出于索引或兼容性考虑可能要求统一全大写(如 "TEST EXAMPLE")。这种多级转换不应散落在控制器中硬编码,而应由模型自身职责化、可复用地完成。

Laravel 9+ 推荐使用 Illuminate\Database\Eloquent\Casts\Attribute 实现双向自动转换。它替代了旧版 accessor/mutator 方法,语法更清晰,且天然支持类型安全与链式调用。

以下以 name 字段为例,展示完整实现:

  1. // app/Models/Example.php 
  2. use Illuminate\Database\Eloquent\Model; 
  3. use Illuminate\Database\Eloquent\Casts\Attribute; 
  4. use Illuminate\Support\Str; 
  5.  
  6. class Example extends Model 
  7.     protected $fillable = ['name']; 
  8.  
  9.     protected function name(): Attribute 
  10.     { 
  11.         return Attribute::make( 
  12.             // 获取时:数据库值 → 模型属性值(全大写 → 首字母大写) 
  13.             get: fn ($value) => Str::ucwords(Str::lower($value)), 
  14.             // 设置时:模型属性值 → 数据库值(首字母大写 → 全大写),同时兼容 JSON 输入(小写 → 全大写) 
  15.             set: fn ($value) => Str::upper((string) $value
  16.         ); 
  17.     } 
✅ 关键说明:

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())和属性转换协同完成——你只需专注定义「值该如何流转」,框架负责执行。

Tags: Laravel数据模型 JSON模型属性

分享到: