Day 19 在暫存複本上第一次跑 PHPStan,抓到 7 個錯誤。今天討論一個延伸問題:如果把 PHPStan 真的接進 CI、常態化持續跑下去,會不會只有「第一次抓到一批,之後就乾淨了」,還是會持續冒出新的警告?
Day 19 的 7 個錯誤是「第一次跑」抓到的存量問題——這批問題已經在程式碼裡待了一段時間,只是沒有工具去檢查而已。如果把 PHPStan 接進 CI 常態化跑下去,接下來要面對的是增量問題:每一次新的 commit,都有機會帶進新的型別不一致,如果沒有持續在跑,這些新問題會像 Day 19 那批一樣,一直累積到某天才被一次性發現。
一次性掃描抓的是「已經欠了多久的債」,常態化整合抓的是「不要再欠新的債」——兩者都需要,但解決的是不同時間軸上的問題。
Day 19 用的是 level 5(PHPStan 的規則等級從 0 到 9,數字越高規則越嚴格)。這裡可以做一個合理推論(沒有在這個系列裡實際跑過更高等級,所以用「推論」而不是「實測結果」):Day 16 提到這個套件的程式碼「沒有用到 PHP 8 限定語法」,某種程度上也代表這批程式碼沒有機會用上 PHP 8 的型別系統改進(例如更精確的 union type、唯讀屬性),如果調高規則等級到更嚴格的層級,PHPStan 很可能會針對「沒有明確標註型別」「回傳型別可以更精確」這類問題,冒出比 level 5 更多的警告——因為等級越高,PHPStan 對「型別標註是否夠精確」的要求也越高,而這批程式碼的型別標註風格,本來就停留在比較寬鬆的階段(前面看過 HasCreditFields 裡很多 getter 只寫 @return string|null 這種寬鬆標註,沒有再往下細分)。
❌ 一次把規則等級調到最高(level 9)
parameters:
level: 9
paths:
- src
# 結果:可能冒出上百個警告,多數是「型別標註不夠精確」這類低急迫性問題
# 開發者被大量警告淹沒,容易乾脆放棄治療
✅ 從能穩定通過的等級開始,逐步調高
parameters:
level: 5 # 先讓這個等級的問題(Day 19 的 7 個)處理乾淨
paths:
- src
# 穩定之後,之後再考慮調到 level 6、7...
# 每次只面對「調高一級後新冒出的那一批」,逐步消化
正例的策略跟 Day 19 提到的「發現問題跟決定怎麼修是兩個層次」呼應——規則等級不是一次到位的事,是隨著團隊處理存量問題的能力,逐步往上調的過程。一次衝到最高等級,換來的通常不是更高的品質,是開發者面對滿螢幕警告後的疲乏跟放棄。
如果你的專案要導入靜態分析工具,你會選擇從最寬鬆的等級開始逐步收緊,還是想清楚目標等級後一次到位?兩種策略你猜哪一種在你的團隊裡比較容易堅持下去?
明天收斂第四部這幾天做的所有補救示範——哪些只是這個系列的示範用途,哪些值得真的推回這個公開套件,這件事該怎麼判斷。