跳转到主要内容

什么是 PHP 属性

PHP 属性(PHP Attributes)是 PHP 8.0 引入的原生元数据语法。可以对类、方法、属性、函数等以 #[AttributeName] 形式附加元信息。 Laravel 在框架内部积极采用 PHP 属性,可以以声明式的方式配置 Job 与 Eloquent Model。Laravel 13(v13.2.0)中队列属性还开始接受 enum。相较于以往通过类属性或方法覆写来设置,使用属性可以写出更易读、更简洁的代码。
属性在 PHP 8.0 及以上可用。Laravel 13 要求 PHP 8.3 及以上,因此在所有环境中都能使用属性。

队列相关属性

队列 Job 相关的属性都位于 Illuminate\Queue\Attributes 命名空间。

#[Queue] — 指定队列名

指定 Job 派发的默认队列名。
从 v13.2.0 起,除了字符串也可以传入 enum。
#[Queue] 属性的 target 被设置为 Attribute::TARGET_CLASS,因此只能用在类上。

#[Connection] — 指定连接

指定 Job 使用的默认队列连接。
同样也支持 enum。

#[Backoff] — 指定重试的退避时间

指定 Job 失败后重试前的等待时间(秒)。可传多个值为不同次重试指定不同等待时间(支持可变参数)。
Backoff 类的实现,它接收可变参数。
单值时保存为 int,多值时保存为 array

#[Tries] — 指定重试次数

指定 Job 失败时的最大重试次数。

#[Timeout] — 指定超时时间

指定 Job 的最大执行时间(秒),超过则会被强制终止。

#[MaxExceptions] — 指定允许的异常次数

发生指定次数以上的异常时,将 Job 视为失败。通常与 #[Tries] 搭配使用。

#[UniqueFor] — 指定唯一周期

指定阻止 Job 重复执行的锁定周期(秒)。与 ShouldBeUnique 一起使用。

#[DeleteWhenMissingModels] — 模型不存在时删除

当 Job 依赖的 Eloquent 模型不存在时,将该 Job 视为删除(跳过)而不是失败。

#[WithoutRelations] — 排除关联

在 Job 序列化时不包含模型的关联,可以让入队数据更小。

#[FailOnTimeout] — 超时视为失败

发生超时时把 Job 记录为失败(默认情况下超时不会记录为失败)。

组合多个队列属性

将这些属性组合可以以声明方式配置 Job 的行为。

Eloquent 相关属性

Eloquent 模型属性位于 Illuminate\Database\Eloquent\Attributes 命名空间。Laravel 13 中新增了大量属性。

#[ScopedBy] — 指定全局作用域

以属性形式指定要自动应用到模型上的全局作用域类。支持继承,通过 IS_REPEATABLE 标志可以指定多个作用域。
要绑定多个作用域时,可重复使用属性或以数组形式传入。
与传统的 booted() 方法对比。

#[ObservedBy] — 指定 Observer

以属性形式指定模型关联的 Observer 类。与 ScopedBy 一样是 IS_REPEATABLE
也可以指定多个 Observer。
无需再在 AppServiceProvider 中注册。

#[UseEloquentBuilder] — 指定自定义 Query Builder

以属性形式指定模型所使用的自定义 Eloquent Builder。

#[CollectedBy] — 指定自定义 Collection

以属性形式指定模型作为集合时使用的自定义 Collection 类。

#[Table] — 一次指定表相关配置

在一个属性中指定表名、主键、时间戳等多个表相关配置。
Table 属性可配置的选项如下。

#[Scope] — 将方法定义为本地作用域

可以把没有 scope 前缀的方法定义为 Eloquent 本地作用域。

#[UseFactory] — 指定 Factory 类

以属性形式指定模型使用的自定义 Factory 类。

其他 Eloquent 属性

Enum 支持(v13.2.0 新增)

在 v13.2.0 中,#[Queue]#[Connection] 开始接受 enum。你可以用 PHP enum 而非字符串字面量来类型安全地指定队列与连接。
使用 enum 可以防止队列名或连接名的拼写错误,也能获得 IDE 补全。适合在应用中统一管理队列与连接名。

与传统类属性的对比

属性的优点

  • 声明式 — 一眼就能看出 Job 的行为
  • 类型安全 — 使用 enum 能获得 IDE 补全与类型检查
  • 与继承兼容 — 子类可覆盖父类的属性
  • 代码更精简 — 无需属性声明或方法覆写

属性的缺点

  • 不能设置动态值 — 属性参数只能是编译期常量,无法使用变量或配置文件的值
  • 需要熟悉 — 团队可能需要熟悉 PHP 8 的属性语法

需要动态值时

想在运行时决定值时,仍使用传统的方法覆写。
属性会在 PHP 编译阶段解析,无法使用 config()env() 等运行时值。需要动态配置时请继续使用类属性或方法。

实现机制

Laravel 内部使用 Reflection API 读取属性。当 Queue Worker 派发 Job 时,ReadsQueueAttributes trait(包含在 InteractsWithQueue 中)会通过反射发现属性并把值写入相应属性。
Eloquent 模型的属性同样通过反射在 Model::booted() 对应时机被读取。

下一步

中级:队列与 Job

学习 Laravel 队列系统的基本用法。

PHP Reflection API

详解 Laravel 用于读取属性的 Reflection API 的机制。
最后修改于 2026年7月18日