PHP の静的解析ツールとしては、
- PHPStan
- Psalm
がよく知られており、いずれも現在も活発に利用されているツールです。
Laravel 界隈では PHPStan(+ Larastan)を採用しているプロジェクトをよく見かけますが、 Psalm も同様に高機能な静的解析ツールとして知られており、
PHPStan と Psalm は何が違うのか? どちらを選択すべきなのか?
という点については、一度整理しておきたいと感じていました。
ここでは、phpstan/phpstan の Discussion の以下のスレッドを拾い読みしながら、その内容を読み解いたうえで、両ツールの設計思想や得意分野の違いについて整理しておきます。
PHPStan compared to other static analysis tools · phpstan/phpstan · Discussion #8986
https://github.com/phpstan/phpstan/discussions/8986
(Mar 2, 2023)
どちらが優れているのか?
まず、Discussion 全体を通して繰り返し触れられているのは、
PHPStan と Psalm は「どちらが優れているか」という関係ではない
という点です。
両者は内部の型推論アルゴリズムや解析戦略が異なっており、 同じコードベースに対して実行した場合でも、検出される問題の内容は完全には一致しないようです。
Discussion の中では、
検出できる問題の約 90% は共通しているが、 残りの 10% は互いに異なる問題を検出する
といった趣旨のコメントも見られました。
つまり、解析の「能力差」というよりも、 見ている観点の違いが結果に現れるツールである、という理解が近そうです。
設計思想の違い
Discussion のやり取りを読んでいると、両者の違いは機能の有無というよりも、 設計思想の方向性にあるように感じられます。
PHPStan の方向性
PHPStan は、
- 実務的なコードベースへの適用を重視している
- 完全に型付けされていない PHP コードを前提としている
- strictness を段階的に上げていく運用を想定している
といった、「既存コードへの導入のしやすさ」を意識した設計になっているようです。
Discussion の中でも、現実のプロジェクトに適用しやすいという点が言及されており、 既存コードを大きく書き換えることなく導入できるツールとして使われているケースが多いようです。
Psalm の方向性
一方で Psalm は、
- 型の整合性をより厳密に検証する
- Generic / Template 型の扱いが強力
- Immutable などの概念も扱える
といった、より型安全性を重視したアプローチを取っているようです。
コードベースを「型安全な状態」に近づけていくことを目的とした設計になっており、 PHPStan と比較すると、より理想的な型設計を要求する傾向があるように見えます。
導入時の体感差
Discussion の内容から読み取れる範囲では、
- PHPStan は比較的導入しやすい
- Psalm は型の整合性をより強く要求する
という傾向があるようです。
そのため、Psalm は導入初期において:
- 既存コードへの修正要求が多くなる
- false positives が多く感じられる
といった friction が発生する可能性についても言及されていました。
フレームワークとの親和性
PHPStan の特徴として、
Extension API が比較的シンプルで、 フレームワーク向けのカスタム対応を書きやすい
といった点も挙げられていました。
Laravel における Larastan のような拡張が存在しているのは、 こうした構造によるものと考えられます。
Service Container や Facade、Eloquent の動的プロパティなど、 静的解析が難しい構造に対しても、フレームワーク側の事情を考慮した解析が可能になります。
両方使うという選択肢
Discussion の中では、
大規模プロジェクトでは両方をCIで回している
という事例にも触れられていました。
両者は検出できる問題の種類が完全には一致しないため、 併用することで検出範囲を広げるという考え方もあるようです。
選定の観点
読み取れる範囲で整理すると、選定の観点は以下のようになります。
| 目的 | 適したツール |
|---|---|
| 既存コードの改善 | PHPStan |
| Laravelプロジェクト | PHPStan |
| 型安全性の向上 | Psalm |
| 設計の厳密性重視 | Psalm |
| 検出範囲の拡張 | 両方併用 |
まとめ
PHPStan は実務コードへの適用を意識したツール、 Psalm は型安全性を重視したツール、
といった設計思想の違いがあり、 目的に応じて選択するのがよさそうです。
Laravel プロジェクトにおいては、 まず PHPStan(+ Larastan)を主軸に導入し、 必要に応じて Psalm の併用を検討する、という使い方が現実的な落としどころになるのではないかと思います。