7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PHPStanAdvent Calendar 2023

Day 23

bleedingEdgeとは何か、いますぐ有効にすべき設定10選

Posted at

PHPStanのリリースの多くには「Bleeding edge 🔪」という節があることに気付くと思います。

bleeding edgeは「最前線」とか「最先端」とかの意味がある言葉ですが、実際に意味するところは「人柱版」です。

PHPStanは日々さまざまな改良が加えられ続けていて、かなり高い頻度でリリースされています。これを有効にすることでさまざまな恩恵が受けられるものの、変更にはかなりアグレッシブなものも含まれています。

一方でPHPStanは現在となっては業務でも多く利用されているもので、頻繁にめちゃくちゃな変更が入ってしまっては困るという人も少なくはないでしょう。

bleedingEdgeはPHPStanが活発な成長と安定性を両立するためのアイディアです。PHPStanの破壊的な変更は基本的にフィーチャーフラグで管理されており、個別に有効化することで機能するようになります。bleedingEdgeは次期メジャーバージョン(2.0)で有効化される計画の先進的な機能を一括で有効化するものです。

PHPStanをbleedingEdgeとして利用するにはPHPStanの設定ファイルに以下の行を追加するだけです。

phpstan.neon
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で有効化されるものなので、みなさんも未来に生きましょう。

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?