Laravel 13 现在允许你使用原生 PHP 属性(attributes)来替换大多数模型中占据大量空间的 $table、$fillable 和 $casts 属性。这一变化适用于十几个框架特性,从模型配置到事件监听器和邮件 (mailables),并且可以在不破坏现有代码的情况下工作。
为什么 Laravel 要引入原生属性
Laravel 长期以来一直依赖“魔术字符串”——即位于模型类顶部的列名或隐藏字段数组。这些数组无法为 IDE 提供底层架构的任何提示,因此在重构列名时可能会被忽略。通过将配置移至真实的、类型化的代码中,Laravel 让开发者能够让类体专注于业务逻辑,同时让编辑器能够提供自动补全、类型检查和重命名重构工具。
框架通过 PHP 的 reflection API 读取属性并缓存结果,因此运行时开销实际上为零。基于属性的现有模型将继续按原样工作,这意味着你可以逐步采用新语法。
你能获得什么
- 类型化配置 – 属性接受类型化的参数,消除了魔术字符串。重命名列时,IDE 会指出所有需要更新的地方。
- 更简洁的类体 – 所有配置都位于类名上方;类体仅包含关系 (relationships)、作用域 (scopes) 和方法。
- 更好的 IDE 体验 – 自动补全和静态分析可以作用于属性参数,这是字符串数组无法提供的。
- 无破坏性变更 – Laravel 同时读取旧属性和新属性,因此混合代码库可以无缝运行。
逐步迁移指南
确定要迁移的模型
打开模型文件。如果前十几行主要是$table、$fillable、$hidden或casts()方法,那么它就是一个候选对象。添加属性类
在文件顶部,导入与你将要替换的属性相对应的属性类(例如Table、Fillable、Casts)。Laravel 开箱即用提供了这些属性。用属性替换属性声明
// Before protected $table = 'site_deployments'; protected $fillable = ['site_id', 'server_id', 'status']; protected function casts(): array { return ['is_rollback' => 'boolean']; }// After #[Table('site_deployments')] #[Fillable(['site_id', 'server_id', 'status'])] #[Casts(['is_rollback' => 'boolean'])] class Deployment extends Model { // business logic only }属性语法直接位于类声明上方。在确认属性工作正常后,删除原始属性或方法。
运行测试套件
验证批量赋值 (mass-assignment)、序列化 (serialization) 和任何自定义类型转换 (casting) 是否仍与以前的行为一致。Laravel 的属性处理是经过缓存的,因此测试失败通常指向属性参数中的拼写错误。分批提交并部署
将迁移后的模型推送到功能分支 (feature branch),在 CI 流水线通过后进行合并,并将其部署到部分服务器。由于仍支持旧的属性语法,任何遗留引用都不会导致运行时错误。按命名空间重复操作
不要一次性重写整个代码库,而是将一组逻辑模型(例如所有与计费相关的实体)迁移到属性,然后对下一组重复此操作。这可以限制任何回归 (regression) 的影响范围。
工具与安全保障
- Rector – 一个自动化重构工具,可以将重复的属性语法转换为属性。在代码库副本上运行它,查看差异 (diff),并应用看起来正确的更改。
- 自动化测试 – Laravel 内置的测试工具可以捕获批量赋值和 JSON 输出中的差异。在每个迁移步骤后保持测试通过 (green)。
- 特性开关 (Feature flags) – 如果你需要快速回滚,可以将新的属性用法封装在开关之后,以便在旧配置和新配置之间切换。
何时可以跳过迁移
如果项目规模较小、运行稳定且很少改动,那么更简洁的模型带来的收益可能抵不上转换所花费的精力。属性语法是可选的;你可以无限期地继续使用传统的属性方法。相反,对于活跃开发的应用,特别是那些具有大型模型或频繁架构变更的应用,尽早采用属性可以减少未来的摩擦。
后续关注点
Laravel 13 的属性支持不仅限于模型,还扩展到了事件监听器、通知、邮件和广播事件。随着社区在这些领域采用该语法,类似的重构模式将会出现。请密切关注官方升级指南,了解未来次要版本中推出的任何新属性类。
核心总结: Laravel 13 为你提供了一条零成本路径,让模型变得更精简、对 IDE 更友好。通过逐个命名空间进行转换,并依靠 Rector 和你的测试套件,你最终得到的类将读起来像业务规范,而非配置堆砌文件。
