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 標準任務的鍵,因為在合併標準任務與套件任務時,相同的字串鍵也會被覆寫。
在標準任務之後執行
在確認的實作中,兩個指令都會先將套件的註冊陣列展開到標準任務的陣列中,再依序呼叫。使用不衝突的鍵時,套件任務會被加在標準任務之後。
基於這個順序,產生指令不應重建其他標準快取,而只產生套件所擁有的資料。請不要把
optimizes() 當作控制多個套件之間相依順序的 API;若需要嚴格的順序,請明確排列專用指令。
以鍵或指令名稱排除
兩個指令的--except 都接受以逗號分隔的值。系統會去除每個值前後的空白,並排除與任務鍵或指令名稱相符的項目。
cache:clear。cache 是任務的鍵,並不是套件專用的名稱。
排除指定只對該次執行有效。它不是用來停用提供者的註冊,或自動刪除先前建立之套件快取的設定。
區分任務的 FAIL 與父指令的結束代碼
OptimizeCommand 與 OptimizeClearCommand 會以 callSilently() 呼叫各任務,並將結束代碼是否為 0 傳給任務顯示。由於一般子指令的輸出不會顯示,調查原因時請直接執行專用指令。
在 Laravel v13.35.0 中,兩者的 handle() 即使子指令回傳非零值,也不會將該值作為父指令的回傳值。即使畫面上顯示 FAIL,迴圈仍會繼續,若沒有例外,父指令的結束代碼就會是 0。另一方面,拋出的例外會在任務顯示元件中重新拋出,因此不會有相同的繼續執行行為。
若套件的產生是部署的必要條件,請採用能直接確認子指令結束代碼的步驟。例如,下列範例將套件任務從批次執行中排除,並在標準任務之後直接執行一次。
courier:cache 的失敗反映在結束代碼上,但並不會彙整標準任務的非零結束。若部署也需要嚴格偵測標準任務,請個別執行所需的指令並確認其結束代碼。
經得起更新的快取設計與確認
除了註冊之外,也要事先決定指令與讀取端的職責。- 產生即使重複執行,也應從相同輸入得到相同狀態,且中途失敗時不應讓不完整的資料生效。
- 刪除在快取不存在時也應正常完成,且不刪除使用者已公開的設定或永久資料。
- 產生失敗的指令應回報錯誤並回傳非零值。讀取端也不應無條件將損壞的快取視為正常。
- 變更快取格式時,請告知使用者需要重新產生,並考慮重新啟動長時間執行的程序。
相關頁面
套件設定的合併與快取
確認已公開設定的補全與設定快取重建之間的關係。
以 Orchestra Testbench 測試 Laravel 套件
在測試環境中註冊提供者與 Artisan 指令。