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

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

https://phpstan.org/blog/what-is-bleeding-edge

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

https://tenshoku.mynavi.jp/engineer/z/dictionary/15/

[人柱版]: https://tenshoku.mynavi.jp/engineer/z/dictionary/15/

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

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

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

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

```yaml:phpstan.neon
includes:
    - phar://phpstan.phar/conf/bleedingEdge.neon
```

`includes:` は別の設定ファイルを読み込むものなので、具体的にどんな項目があるのかは設定ファイルで確認できます。

https://github.com/phpstan/phpstan-src/blob/1.10.x/conf/bleedingEdge.neon

公式に推奨する`bleedingEdge.neon`を読み込む方法で一括有効化しなくても個別に設定できるものがあるので、この記事ではわかりやすいもの、ぜひ有効化すべきものから10個選んで紹介します。

## 最重要：パフォーマンス改善

`nodeConnectingVisitorCompatibility: false`を無効化するとパフォーマンスがかなり改善するはずです。(この記事で紹介する他の設定項目とは異なり、***この設定は無効化することで効果を発揮します***)

```yaml
parameters:
    featureToggles:
        nodeConnectingVisitorCompatibility: false
        nodeConnectingVisitorRule: true
```

具体的にどのように改善するかはPHPStan 1.6.0リリース時の記事をお読みください。

https://www.phper.ninja/entry/2022/04/28/015632

`nodeConnectingVisitorRule: true`と設定することで、この設定によって非互換になる属性に依存した箇所を検出できるルールが有効化されるので合せて設定してもいいでしょう。

:::note
この設定を有効化する上でのデメリットは古い互換性のないPHPStan拡張が動かなくなることくらいなので、変なextensionを導入しない限りはさくっと有効化する第一候補です。
:::

## bleedingEdge

`bleedingEdge: true` にすると細かい後方互換性を損なう変更が有効化されます。

```yaml
parameters:
    featureToggles:
        bleedingEdge: true
```

:::note
このフラグを立てるだけでは実際そんなに劇的なことは起こらないと思うので軽率に有効化しちゃっていいと思いますよ。
:::

## stricterFunctionMap

`stricterFunctionMap: true` にすると標準関数のパラメータ検証がやや厳しくなります。

```
parameters:
    featureToggles:
        stricterFunctionMap: true
```

具体的には標準関数の型宣言が[`functionMap.php`]よりも厳しい[`functionMap_bleedingEdge.php`]が読み込まれることで、入力値の検査が厳しくなります。なのですが、ほとんどの箇所では影響ないと思います。

[`functionMap.php`]: https://github.com/phpstan/phpstan-src/blob/1.10.x/resources/functionMap.php
[`functionMap_bleedingEdge.php`]: https://github.com/phpstan/phpstan-src/blob/1.10.x/resources/functionMap_bleedingEdge.php

## listType

`listType: true` にすると[list型]が追加されます。

```yaml
parameters:
    featureToggles:
        listType: true
```

有効化しない状態ではlist型実装前と同じ `array<int, T>` として扱われます。つまり、`T[]`と`array<T>`と`list<T>`と`array<int,T>`を同一視してしまっているようなコードで、よりよく区別できるようになります。

[list型]: https://scrapbox.io/php/list%E5%9E%8B

## duplicateStubs

`duplicateStubs: true` にすると、スタブファイルに重複定義ががあると警告されるようになります。

```yaml
parameters:
    featureToggles:
        duplicateStubs: true
```

:::note
自前のスタブを運用してなければ特に問題はないのではないのでしょうか。
:::

## readOnlyByPhpDoc

`readOnlyByPhpDoc: true` にすると、PHPDocの `@readonly` を静的にチェックできるようになります。

```yaml
parameters:
    featureToggles:
        readOnlyByPhpDoc: true
```

:::note
すぐにPHP 8.xにアップデートできないような状況ではかなり有用なほか、`@phpstan-readonly-allow-private-mutation`も利用できるのでかなり実用性があると思います。
:::

## finalByPhpDoc

`finalByPhpDoc: true` にすると、PHPDocの `@final` を静的にチェックできるようになります。

```yaml
parameters:
    featureToggles:
        finalByPhpDoc: true
```

たとえば、アプリケーション内では継承させたくないがテストコードでモックライブラリを利用してテストダブルに差し替えたい、というときに有用です。

## varTagType

`varTagType: true` にすると、`@var`でありえない型にしようとしたときに警告されるようになります。

```yaml
parameters:
    featureToggles:
        varTagType: true
```

この機能についてはPHPStan 1.10リリース時の「[PHPStan 1.10には嘘発見器が付属しています]」という記事で詳しく紹介されています。

https://www.phper.ninja/entry/2023/02/22/210803

:::note warning
現実には警告されてでも使わざるを得ない場面というのもいくつかあるのですが、別の機会に紹介しましょう。
:::

[PHPStan 1.10には嘘発見器が付属しています]: https://www.phper.ninja/entry/2023/02/22/210803

## logicalXor

`logicalXor: true` にすると `xor` 演算子が常に `true` になるような場面をきちんと検査してくれるようになります。

```yaml
parameters:
    featureToggles:
        logicalXor: true
```

なんでデフォルトで有効化してくれないんだレベルの機能なので、さくっと有効化すると良いのではないでしょうか。~~まあ、そもそもプログラムで `xor` 演算をする機会がそんなに多くないですが…~~

## allInvalidPhpDocs, invalidPhpDocTagLine

`allInvalidPhpDocs: true` にすると、PHPDocエラーの検査対象が拡がります。

`invalidPhpDocTagLine: true` にすると、PHPDocエラーに行数が含まれるようになります。

```yaml
parameters:
    featureToggles:
        allInvalidPhpDocs: true
        invalidPhpDocTagLine: true
```

これも互換性のための設定なので、さくっと有効化するのがいいでしょう。

# まとめ

いかがでしたでしょうか。個人的には細かいことを気にせず全部まとめて有効化しちゃえばいいと思いますが…

言い換えれば、これらの項目はPHPStan 1.0リリース後から現在までのPHPStanの改善の軌跡ということもできます。まあすごく地味なものや、とても説明のしにくいものも多いので今回は有用なものを10個だけ紹介した次第です。

これらの機能はPHPStan 2.0で有効化されるものなので、みなさんも未来に生きましょう。