Laravel 13 现在允许你使用原生 PHP 属性(attributes)来替换大多数模型中占据大量空间的 $table$fillable$casts 属性。这一变化适用于十几个框架特性,从模型配置到事件监听器和邮件 (mailables),并且可以在不破坏现有代码的情况下工作。

为什么 Laravel 要引入原生属性

Laravel 长期以来一直依赖“魔术字符串”——即位于模型类顶部的列名或隐藏字段数组。这些数组无法为 IDE 提供底层架构的任何提示,因此在重构列名时可能会被忽略。通过将配置移至真实的、类型化的代码中,Laravel 让开发者能够让类体专注于业务逻辑,同时让编辑器能够提供自动补全、类型检查和重命名重构工具。

框架通过 PHP 的 reflection API 读取属性并缓存结果,因此运行时开销实际上为零。基于属性的现有模型将继续按原样工作,这意味着你可以逐步采用新语法。

你能获得什么

  • 类型化配置 – 属性接受类型化的参数,消除了魔术字符串。重命名列时,IDE 会指出所有需要更新的地方。
  • 更简洁的类体 – 所有配置都位于类名上方;类体仅包含关系 (relationships)、作用域 (scopes) 和方法。
  • 更好的 IDE 体验 – 自动补全和静态分析可以作用于属性参数,这是字符串数组无法提供的。
  • 无破坏性变更 – Laravel 同时读取旧属性和新属性,因此混合代码库可以无缝运行。

逐步迁移指南

  1. 确定要迁移的模型
    打开模型文件。如果前十几行主要是 $table$fillable$hiddencasts() 方法,那么它就是一个候选对象。

  2. 添加属性类
    在文件顶部,导入与你将要替换的属性相对应的属性类(例如 TableFillableCasts)。Laravel 开箱即用提供了这些属性。

  3. 用属性替换属性声明

    // 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
    }
    

    属性语法直接位于类声明上方。在确认属性工作正常后,删除原始属性或方法。

  4. 运行测试套件
    验证批量赋值 (mass-assignment)、序列化 (serialization) 和任何自定义类型转换 (casting) 是否仍与以前的行为一致。Laravel 的属性处理是经过缓存的,因此测试失败通常指向属性参数中的拼写错误。

  5. 分批提交并部署
    将迁移后的模型推送到功能分支 (feature branch),在 CI 流水线通过后进行合并,并将其部署到部分服务器。由于仍支持旧的属性语法,任何遗留引用都不会导致运行时错误。

  6. 按命名空间重复操作
    不要一次性重写整个代码库,而是将一组逻辑模型(例如所有与计费相关的实体)迁移到属性,然后对下一组重复此操作。这可以限制任何回归 (regression) 的影响范围。

工具与安全保障

  • Rector – 一个自动化重构工具,可以将重复的属性语法转换为属性。在代码库副本上运行它,查看差异 (diff),并应用看起来正确的更改。
  • 自动化测试 – Laravel 内置的测试工具可以捕获批量赋值和 JSON 输出中的差异。在每个迁移步骤后保持测试通过 (green)。
  • 特性开关 (Feature flags) – 如果你需要快速回滚,可以将新的属性用法封装在开关之后,以便在旧配置和新配置之间切换。

何时可以跳过迁移

如果项目规模较小、运行稳定且很少改动,那么更简洁的模型带来的收益可能抵不上转换所花费的精力。属性语法是可选的;你可以无限期地继续使用传统的属性方法。相反,对于活跃开发的应用,特别是那些具有大型模型或频繁架构变更的应用,尽早采用属性可以减少未来的摩擦。

后续关注点

Laravel 13 的属性支持不仅限于模型,还扩展到了事件监听器、通知、邮件和广播事件。随着社区在这些领域采用该语法,类似的重构模式将会出现。请密切关注官方升级指南,了解未来次要版本中推出的任何新属性类。

核心总结: Laravel 13 为你提供了一条零成本路径,让模型变得更精简、对 IDE 更友好。通过逐个命名空间进行转换,并依靠 Rector 和你的测试套件,你最终得到的类将读起来像业务规范,而非配置堆砌文件。