本頁為 Laravel 套件開發、以 Orchestra Testbench 測試 Laravel 套件、套件的版本相容性管理 的輔助指南。將靜態分析加入實作、測試、版本策略中,可使套件更易長期維護。
什麼是靜態分析
靜態分析是不執行程式碼即能偵測型別不一致或潛在 bug 的手法。Laravel 套件有大量像服務容器、Facade、Eloquent 等動態機制,僅靠動作確認容易疏漏的問題可於早期發現。 導入靜態分析尤其能帶來下列效果。- 提升型別安全性 — 於審查前即可偵測錯誤的引數或回傳值
- 早期發現 bug — 不存在的方法呼叫、nullable 的疏漏可於測試前掌握
- 改善 IDE 補完 — 整理 PHPDoc 與 Generics 可提升補完精度
- 穩定的長期維護 — Laravel 或 PHP 升級時容易篩出損壞處
PHPStan 的設定
首先以 PHPStan 單獨準備分析基礎。PHPStan 2.x 對mixed 或 nullable 的處理較從前嚴格,也是整理套件公開 API 的契機。
1
將 PHPStan 加入開發相依
2
先直接分析目標目錄
套件通常會將
src 與 tests 作為初始目標。3
固定於 Composer script
為讓 CI 與 local 使用相同指令,於
composer.json 定義 script 較易操作。Larastan 的設定
於 Laravel 套件中僅使用 PHPStan 無法充分理解容器解析、Facade、Eloquent 關聯等 Laravel 特有機制。因此併用 PHPStan 的 Laravel 擴充 Larastan。1
加入 Larastan
目前的套件名稱為
larastan/larastan。舊文章中可能出現 nunomaduro/larastan。2
若為套件開發,也一併加入 Testbench
Larastan 會啟動 Laravel 應用程式容器來解析型別。單獨分析 Laravel 套件時,可能需要
orchestra/testbench。3
讀入 extension.neon
於
phpstan.neon include Larastan 的設定。phpstan.neon 的設定
phpstan.neon 是匯總分析等級、對象路徑、排除路徑、例外規則的中心設定。對 Laravel 套件而言,一開始就追求 100 分並不實際,將設定調整為可持續提升較為務實。
以下為 phpstan.neon 範例。
Level 0〜9 的選擇
PHPStan 可分階段導入。從目前程式碼基底能完整通過的等級開始,隨著修正推進再往上調整較為安全。paths
於 paths 明確指定要分析的目錄。套件中除 src 外,也包含容易型別崩壞的 tests 會較有效。
excludePaths
僅排除生成檔案、快取、驗證用 Workbench 等靜態分析價值低的位置。若排除過廣,會連原本要檢出的錯誤也看不到。
ignoreErrors
ignoreErrors 是最後的手段。請以正規表達式限縮訊息,並併用 path 限定影響範圍。將來 Laravel 或 Larastan 改善時較易還原。
常用的型別 annotation
PHPStan 與 Larastan 的精度會因 PHPDoc 的寫法大幅變動。Laravel 套件中,尤其整理@param、@return、@var、Generics(@template)具有高價值。
@param class-string<TModel>— 表示字串不是任意字串,而是 Model 類別名稱@return TModel|null— 告知find()回傳具體的模型型別@var Collection<int, TModel>— 明確指定 collection 的 key / value 型別@template TModel of Model— 表達可重複利用的 generic repository
Laravel 專屬的注意事項
Laravel 的「便利 magic」若不作處理則無法傳遞給靜態分析。需於套件端補上型別資訊,靠向分析器可理解的形式。Facade
在自訂 Facade 上,以 PHPDoc 補述使用者呼叫的方法,可同時對 IDE 與靜態分析生效。魔術方法
依賴__call() 或 Macroable 的 API 雖然方便,但也是型別容易崩壞的地方。若要作為公開 API,新增可辨識回傳值與引數的 wrapper 方法較安全。
Eloquent 模型的型別指定
Eloquent 關聯或動態屬性,結合@property 與 relation 的 Generics 較有效。
於 CI 自動執行
靜態分析不僅於 local,也務必於 CI 執行。特別是支援多個 Laravel 版本的套件,若以與套件的版本相容性管理的 test matrix 相同的思路運轉,可同時監視相容性與型別安全性。 以下為.github/workflows/static-analysis.yml 的範例。
常見的誤判與應對
看到靜態分析的警告時,請先懷疑「是否為型別資訊不足」。看似誤判者,實際上常常只是 PHPDoc 不足。@phpstan-ignore-next-line
可作為暫時的迴避手段,但請僅用於自己能說明理由的行。
ignoreErrors
僅於相同錯誤出現於多處時考慮。務必限縮 path,勿以粗略的正規表達式一概蓋掉整體。
應優先的處理
- 補上 PHPDoc
- 明確指定 Facade 或 relation 的回傳值型別
- 將
mixed替換為具體型別 - 剩下能說明的誤判才 ignore
相關頁面
Laravel 套件開發
確認包含服務提供者與公開資源在內的套件實作基礎。
以 Orchestra Testbench 測試 Laravel 套件
說明希望與靜態分析共同運行的套件測試基礎。
套件的版本相容性管理
確認 Laravel / PHP 的對應表與 GitHub Actions 的 matrix 策略。