Skip to main content
當套件需要預先產生自己的中繼資料時,若只是請使用者在部署步驟中加入專用指令,更新時很容易漏掉執行。使用 ServiceProvider::optimizes(),就能將產生與刪除的指令整合進 Laravel 的 optimize 與 optimize:clear。 本頁以套件開發的基礎為前提,確認 Laravel Framework v13.35.0 的實作。這裡探討的不是快取檔案的格式,而是註冊與維運上的約定。

將指令的註冊與任務的註冊分開

commands() 會註冊可從 Artisan 呼叫的指令類別。optimizes() 則是另一項處理,將已可執行的指令名稱註冊為最佳化任務。只呼叫後者的話,指令類別並不會被註冊。 下列範例的前提是,套件已實作 CacheMetadataCommand 與 ClearMetadataCommand,且兩者的 $signature 分別為 courier:cache 與 courier:clear-cache。
optimizes() 的參數全都可為 null,因此也可以只註冊產生或只註冊刪除。不過,請務必告知使用者要透過哪個步驟讓產生的快取失效。

註冊鍵也會成為面向使用者的約定

ServiceProvider 會將產生指令儲存在靜態陣列 $optimizeCommands,將刪除指令儲存在 $optimizeClearCommands。兩者都以 key 作為陣列鍵。 省略 key 時,會從提供者的類別名稱產生名稱。例如 CourierServiceProvider 會得到 courier。由於只使用類別名稱,即使是位於不同命名空間的同名提供者也可能發生衝突。 以相同的鍵重新註冊時,該側的指令會被後來的值覆寫。若要註冊多個任務,請指定不同的鍵。此外,請避開 config 或 routes 等 Laravel 標準任務的鍵,因為在合併標準任務與套件任務時,相同的字串鍵也會被覆寫。
請像 acme-courier 這樣明確指定能識別套件的鍵,並在各版本之間維持不變。鍵會成為任務的顯示名稱,也是使用者以 --except 指定的值。

在標準任務之後執行

在確認的實作中,兩個指令都會先將套件的註冊陣列展開到標準任務的陣列中,再依序呼叫。使用不衝突的鍵時,套件任務會被加在標準任務之後。 基於這個順序,產生指令不應重建其他標準快取,而只產生套件所擁有的資料。請不要把 optimizes() 當作控制多個套件之間相依順序的 API;若需要嚴格的順序,請明確排列專用指令。
optimize:clear 也包含 cache:clear,會一併刪除預設快取儲存區的資料。若只想清除套件專用的快取,請直接執行 courier:clear-cache。套件的刪除指令本身也應設計成不 flush 整個共用儲存區,只刪除自己擁有的鍵或檔案。

以鍵或指令名稱排除

兩個指令的 --except 都接受以逗號分隔的值。系統會去除每個值前後的空白,並排除與任務鍵或指令名稱相符的項目。
前兩行排除的是同一個產生任務。第三行則排除套件的刪除任務,以及標準的 cache:clear。cache 是任務的鍵,並不是套件專用的名稱。 排除指定只對該次執行有效。它不是用來停用提供者的註冊,或自動刪除先前建立之套件快取的設定。

區分任務的 FAIL 與父指令的結束代碼

OptimizeCommand 與 OptimizeClearCommand 會以 callSilently() 呼叫各任務,並將結束代碼是否為 0 傳給任務顯示。由於一般子指令的輸出不會顯示,調查原因時請直接執行專用指令。 在 Laravel v13.35.0 中,兩者的 handle() 即使子指令回傳非零值,也不會將該值作為父指令的回傳值。即使畫面上顯示 FAIL,迴圈仍會繼續,若沒有例外,父指令的結束代碼就會是 0。另一方面,拋出的例外會在任務顯示元件中重新拋出,因此不會有相同的繼續執行行為。
請不要僅憑 php artisan optimize 的結束代碼為 0,就判斷套件快取已成功產生。此行為是基於所確認版本的實作,因此在更新支援的 Laravel 版本時也請重新確認。
若套件的產生是部署的必要條件,請採用能直接確認子指令結束代碼的步驟。例如,下列範例將套件任務從批次執行中排除,並在標準任務之後直接執行一次。
此範例會將 courier:cache 的失敗反映在結束代碼上,但並不會彙整標準任務的非零結束。若部署也需要嚴格偵測標準任務,請個別執行所需的指令並確認其結束代碼。

經得起更新的快取設計與確認

除了註冊之外,也要事先決定指令與讀取端的職責。
  • 產生即使重複執行,也應從相同輸入得到相同狀態,且中途失敗時不應讓不完整的資料生效。
  • 刪除在快取不存在時也應正常完成,且不刪除使用者已公開的設定或永久資料。
  • 產生失敗的指令應回報錯誤並回傳非零值。讀取端也不應無條件將損壞的快取視為正常。
  • 變更快取格式時,請告知使用者需要重新產生,並考慮重新啟動長時間執行的程序。
除了套件的測試之外,請在使用端應用程式中確認下列項目。由於註冊陣列是靜態的,也請留意同一程序內各測試之間註冊狀態的殘留。

相關頁面

套件設定的合併與快取

確認已公開設定的補全與設定快取重建之間的關係。

以 Orchestra Testbench 測試 Laravel 套件

在測試環境中註冊提供者與 Artisan 指令。

參考的一手資料

最後修改於 2026年10月6日