PHPStanのリリースの多くには「Bleeding edge 🔪」という節があることに気付くと思います。
bleeding edgeは「最前線」とか「最先端」とかの意味がある言葉ですが、実際に意味するところは「人柱版」です。
PHPStanは日々さまざまな改良が加えられ続けていて、かなり高い頻度でリリースされています。これを有効にすることでさまざまな恩恵が受けられるものの、変更にはかなりアグレッシブなものも含まれています。
一方でPHPStanは現在となっては業務でも多く利用されているもので、頻繁にめちゃくちゃな変更が入ってしまっては困るという人も少なくはないでしょう。
bleedingEdgeはPHPStanが活発な成長と安定性を両立するためのアイディアです。PHPStanの破壊的な変更は基本的にフィーチャーフラグで管理されており、個別に有効化することで機能するようになります。bleedingEdgeは次期メジャーバージョン(2.0)で有効化される計画の先進的な機能を一括で有効化するものです。
PHPStanをbleedingEdgeとして利用するにはPHPStanの設定ファイルに以下の行を追加するだけです。
includes:
- phar://phpstan.phar/conf/bleedingEdge.neon
includes:
は別の設定ファイルを読み込むものなので、具体的にどんな項目があるのかは設定ファイルで確認できます。
公式に推奨するbleedingEdge.neon
を読み込む方法で一括有効化しなくても個別に設定できるものがあるので、この記事ではわかりやすいもの、ぜひ有効化すべきものから10個選んで紹介します。
最重要:パフォーマンス改善
nodeConnectingVisitorCompatibility: false
を無効化するとパフォーマンスがかなり改善するはずです。(この記事で紹介する他の設定項目とは異なり、この設定は無効化することで効果を発揮します)
parameters:
featureToggles:
nodeConnectingVisitorCompatibility: false
nodeConnectingVisitorRule: true
具体的にどのように改善するかはPHPStan 1.6.0リリース時の記事をお読みください。
nodeConnectingVisitorRule: true
と設定することで、この設定によって非互換になる属性に依存した箇所を検出できるルールが有効化されるので合せて設定してもいいでしょう。
この設定を有効化する上でのデメリットは古い互換性のないPHPStan拡張が動かなくなることくらいなので、変なextensionを導入しない限りはさくっと有効化する第一候補です。
bleedingEdge
bleedingEdge: true
にすると細かい後方互換性を損なう変更が有効化されます。
parameters:
featureToggles:
bleedingEdge: true
このフラグを立てるだけでは実際そんなに劇的なことは起こらないと思うので軽率に有効化しちゃっていいと思いますよ。
stricterFunctionMap
stricterFunctionMap: true
にすると標準関数のパラメータ検証がやや厳しくなります。
parameters:
featureToggles:
stricterFunctionMap: true
具体的には標準関数の型宣言がfunctionMap.php
よりも厳しいfunctionMap_bleedingEdge.php
が読み込まれることで、入力値の検査が厳しくなります。なのですが、ほとんどの箇所では影響ないと思います。
listType
listType: true
にするとlist型が追加されます。
parameters:
featureToggles:
listType: true
有効化しない状態ではlist型実装前と同じ array<int, T>
として扱われます。つまり、T[]
とarray<T>
とlist<T>
とarray<int,T>
を同一視してしまっているようなコードで、よりよく区別できるようになります。
duplicateStubs
duplicateStubs: true
にすると、スタブファイルに重複定義ががあると警告されるようになります。
parameters:
featureToggles:
duplicateStubs: true
自前のスタブを運用してなければ特に問題はないのではないのでしょうか。
readOnlyByPhpDoc
readOnlyByPhpDoc: true
にすると、PHPDocの @readonly
を静的にチェックできるようになります。
parameters:
featureToggles:
readOnlyByPhpDoc: true
すぐにPHP 8.xにアップデートできないような状況ではかなり有用なほか、@phpstan-readonly-allow-private-mutation
も利用できるのでかなり実用性があると思います。
finalByPhpDoc
finalByPhpDoc: true
にすると、PHPDocの @final
を静的にチェックできるようになります。
parameters:
featureToggles:
finalByPhpDoc: true
たとえば、アプリケーション内では継承させたくないがテストコードでモックライブラリを利用してテストダブルに差し替えたい、というときに有用です。
varTagType
varTagType: true
にすると、@var
でありえない型にしようとしたときに警告されるようになります。
parameters:
featureToggles:
varTagType: true
この機能についてはPHPStan 1.10リリース時の「PHPStan 1.10には嘘発見器が付属しています」という記事で詳しく紹介されています。
現実には警告されてでも使わざるを得ない場面というのもいくつかあるのですが、別の機会に紹介しましょう。
logicalXor
logicalXor: true
にすると xor
演算子が常に true
になるような場面をきちんと検査してくれるようになります。
parameters:
featureToggles:
logicalXor: true
なんでデフォルトで有効化してくれないんだレベルの機能なので、さくっと有効化すると良いのではないでしょうか。まあ、そもそもプログラムで xor
演算をする機会がそんなに多くないですが…
allInvalidPhpDocs, invalidPhpDocTagLine
allInvalidPhpDocs: true
にすると、PHPDocエラーの検査対象が拡がります。
invalidPhpDocTagLine: true
にすると、PHPDocエラーに行数が含まれるようになります。
parameters:
featureToggles:
allInvalidPhpDocs: true
invalidPhpDocTagLine: true
これも互換性のための設定なので、さくっと有効化するのがいいでしょう。
まとめ
いかがでしたでしょうか。個人的には細かいことを気にせず全部まとめて有効化しちゃえばいいと思いますが…
言い換えれば、これらの項目はPHPStan 1.0リリース後から現在までのPHPStanの改善の軌跡ということもできます。まあすごく地味なものや、とても説明のしにくいものも多いので今回は有用なものを10個だけ紹介した次第です。
これらの機能はPHPStan 2.0で有効化されるものなので、みなさんも未来に生きましょう。