Skip to main content

什麼是 PHP Attributes

PHP Attributes 是 PHP 8.0 導入的原生 metadata 語法。可對類別、方法、屬性、函式等以 #[AttributeName] 形式加註元資訊。 Laravel 於框架本體積極採用 PHP Attributes,可以宣告式撰寫 Job 或 Eloquent 模型的設定。於 Laravel 13(v13.2.0)中,Queue attribute 可接受 enum。相較於傳統的類別屬性或方法覆寫,使用 attribute 可寫出更易讀且簡潔的程式碼。
Attributes 於 PHP 8.0 以後可使用。Laravel 13 要求 PHP 8.3 以上,因此所有環境皆可使用 attribute。

Queue 相關 Attributes

Queue Job 相關的 attributes 皆位於 Illuminate\Queue\Attributes 命名空間。

#[Queue] — 指定 Queue 名稱

指定 Job 送往的預設 Queue 名稱。
自 v13.2.0 起,可傳入 enum 代替字串。
#[Queue] attribute 的 target 被設為 Attribute::TARGET_CLASS,因此只能套用於類別。

#[Connection] — 指定 Connection

指定 Job 使用的預設 Queue Connection。
此處也可使用 enum。

#[Backoff] — 指定重試 backoff 時間

指定 Job 失敗時,重試前的等待時間(秒)。傳入多個值時,每次重試可設定不同的等待時間(可變長引數支援)。
觀察 Backoff 類別的實作,設計為接受可變長引數。
單一值時作為 int 存放,多個值時作為 array 存放。

#[Tries] — 指定重試次數

指定 Job 失敗時的最大重試次數。

#[Timeout] — 指定 Timeout

指定 Job 的最大執行時間(秒)。超過此時間時,Job 會被強制中止。

#[MaxExceptions] — 指定容許例外次數

當發生指定次數以上的例外時,將 Job 視為失敗。搭配 #[Tries] 使用。

#[UniqueFor] — 指定唯一期間

指定防止 Job 重複執行的 lock 期間(秒)。搭配 ShouldBeUnique 使用。

#[DeleteWhenMissingModels] — 模型不存在時刪除

當 Job 相依的 Eloquent 模型找不到時,將 Job 視為刪除(跳過)而非失敗。

#[WithoutRelations] — 排除關聯

於 Job 序列化時不將模型的關聯納入。可精簡送往 Queue 的資料量。

#[FailOnTimeout] — Timeout 時視為失敗

當發生 Timeout 時,將 Job 記錄為失敗(預設 Timeout 不會被記錄為失敗)。

組合多個 Queue Attributes

可以組合這些 attribute,宣告式設定 Job 的行為。

Eloquent 相關 Attributes

Eloquent 模型的 attributes 位於 Illuminate\Database\Eloquent\Attributes 命名空間。Laravel 13 新增了大量 attribute。

#[ScopedBy] — 指定 Global Scope

以 attribute 指定要自動套用至模型的 Global Scope 類別。支援繼承,並具有 IS_REPEATABLE 旗標,可指定多個 Scope。
要套用多個 Scope,重複標註 attribute 或以陣列傳入。
與傳統 booted() 方法的比較。

#[ObservedBy] — 指定 Observer

以 attribute 指定關聯至模型的 Observer 類別。與 ScopedBy 同樣為 IS_REPEATABLE
也可指定多個 Observer。
不再需於傳統的 AppServiceProvider 註冊。

#[UseEloquentBuilder] — 指定自訂 Query Builder

以 attribute 指定模型所使用的自訂 Eloquent Builder。

#[CollectedBy] — 指定自訂 Collection

以 attribute 指定模型的 Collection 所使用的自訂 Collection 類別。

#[Table] — 一次指定 Table 相關設定

可以一個 attribute 一次指定表格名稱、主鍵、時間戳記等多個 Table 相關設定。
Table attribute 可設定的選項如下。

#[Scope] — 將方法定義為本地 Scope

可將不含 scope 前綴的方法定義為 Eloquent 的本地 Scope。

#[UseFactory] — 指定 Factory 類別

以 attribute 指定模型所使用的自訂 Factory 類別。

其他 Eloquent Attributes

Enum 支援(於 v13.2.0 加入)

於 v13.2.0,#[Queue]#[Connection] 開始接受 enum。如此便可使用 PHP enum 取代字串字面值,型別安全地指定 Queue 與 Connection。
使用 enum 可防止 Queue 名稱或 Connection 名稱的拼字錯誤,並可利用 IDE 的補完。適合在整個應用程式集中管理 Queue 名稱與 Connection 名稱。

與傳統類別屬性的比較

Attribute 的優點

  • 宣告式 — 觀察類別開頭即可一眼看出 Job 的行為
  • 型別安全 — 使用 enum 可享有 IDE 補完與型別檢查
  • 與繼承的親和性 — 父類別的 attribute 可於子類別覆寫
  • 減少程式碼 — 不需宣告屬性或覆寫方法

Attribute 的缺點

  • 無法設定動態值 — attribute 的引數僅能為編譯時常數。無法使用變數或設定檔的值
  • 需適應 — 團隊有時需要適應 PHP 8 的 attribute 語法

需要動態值時

若希望於執行時決定值,仍使用傳統的方法覆寫。
Attributes 於 PHP 編譯時被解析。無法使用 config()env() 這類執行時的值。若需要動態設定,請繼續使用類別屬性或方法。

實作機制

Laravel 內部使用 Reflection API 讀取 attribute。當 Queue Worker dispatch Job 時,ReadsQueueAttributes trait(包含於 InteractsWithQueue 中)以 reflection 偵測 attribute,並將值設定至對應屬性。
Eloquent 模型的 attribute 也同樣,於相當於 Model::booted() 的時機以 reflection 讀取。

下一步

中階:Queue 與 Job

學習 Laravel Queue 系統的基本用法。

PHP Reflection API

詳細說明 Laravel 讀取 attribute 所使用的 Reflection API 機制。
最後修改於 2026年8月2日