Using PHPStan with Drupal
Drupal Advent Calendar 2022 5日目の記事です
DrupalでPHPStanを導入してみたいという方に向けて導入方法を解説します。
何ができる?
PHPStan は PHPコードの静的解析ツールです。コードの品質向上のために使います。
解析レベルやルールにもよりますがこれはバグにつながりそう・・・というコードを指摘してくれます。
導入方法
実は Drupal.orgのドキュメント があります。実はこの通りに設定すれば導入できます。
主にやることは以下です。
Composerで必要なプラグインを導入する
PHPStanの解析内容を指定する phpstan.neon ファイルを整備する
実行!!その後コードを修正 or phpstan.neon を見直す
(開発フローでCI/CDに設定するとなお良し)
導入例は以下にアップしています。
https://github.com/kazukomurata/drupal-phpstan
Composerで必要なプラグインを導入する
Getting started のcomposerコマンドの通りなのでそれぞれのプラグインの機能を解説します。
phpstan/phpstan
PHPStanの本体です
phpstan/extension-installer
PHPStanの拡張プラグインをいい感じに読み込んでくれるプラグインです。
mglaman/phpstan-drupal
PHPStanのDrupal拡張プラグインです。
Drupal独特のPHPファイルなどをいい感じ対象にしてくれます。
.module とか .themeとか ・・・
各種モジュールはDrupal Coreに依存していて、bootstrap を読み込まないと動かない&正しく解析できないのですが、この辺りもいい感じにやってくれます。
このプラグインは入れなくても phpstan.neon で地道に定義すればいいのですが導入した方が絶対楽です。
phpstan/phpstan-deprecation-rules
@deprecated のメソッド、関数を指摘してくれます。バージョンアップから逃げられないDrupalにはとても大事。
code:shell
## ざっくり紹介すると、こういうのが出せます
21 Instantiation of deprecated class Drupal\action\Plugin\migrate\source\Action:
in drupal:9.4.0 and is removed from drupal:10.0.0. Use
\Drupal\system\Plugin\migrate\source\Action instead.
非推奨チェックは他にも方法があるので好みでいいと思います。
drupal-checkとかPHPUnit動かすとか
もしPHPUnitのコードもいい感じ解析したい場合は以下のプラグインも追加すると良い感じです。
phpstan/phpstan-phpunit
テストコードもPHPなので無くても解析できるのですが、assertの良い使い方とかこのテストが動いてなさそうなどの指摘がもらえます。
phpsta.neonの例
設定の調整は Config Reference を見てください。
code:yml
parameters:
level: max # 0〜8 max=8
phpVersion: 80100 # PHP 8.1 指定がなければ、実行中のPHPのバージョンで解析
tipsOfTheDay: false # https://phpstan.org/config-reference#tipsoftheday
paths:
# 対象を指定. srcとかのざっくりとしたパス指定も可能.
- docroot/themes/custom
- docroot/modules/custom
bootstrapFiles:
# DrupalのPHPUnitのテストコードを対象にするときはテスト用のbootstrap読み込みが必要.
- docroot/core/tests/bootstrap.php
実行
code:shell
$ vendor/bin/phpstan analyse
# メモリが足りないときはオプションをつける.Composer ScriptsやMakeに定義して楽してもいいかもしれない
$ vendor/bin/phpstan analyse --memory-limit=-1
運用のコツ
まずDrupalのモジュールやテーマはCoreのコードを継承したりサービスをDIしたりする前提で動くコードです。
level をあげるとCore側の仕様起因でNGとなるケースが結構あります。
なぜならばCore側がPHPStanによる修正を絶賛対応中だからです(2022/12/1現在)
例 : Fix 'Call to an undefined method' PHPStan L0 errors
コードの品質向上のために導入するものなので継続して実行できることが大事です。
イマイチ使えないなとおもったら以下を検討してみてください。
levelの調整
max はすごい辛い。(体験談)
コード実装者としてはやるべきだよねと思いつつ
プロジェクト管理目線で対費用効果どうかな?と思うレベルで面倒
0からスタートでも全然よいと思っている
(追記) 1年以上運用して、level 5 が一番上の設定かなと思いました。level 6 になるとrender array が report missing typehints に引っかかって面倒でした
エラー抑制の検討 Ignoring Errors
levelを上げるならエラー抑制は必須
一例はこちら Handling "Unsafe usage of new static()"
おまけ
そもそもDrupalでPHPStan導入してみたいなーと思ったのはドリスのブログでした。
PHPStan以外にも参考になる話が載っているのでぜひみてみてください。
My Drupal deployment workflow
(翻訳版) Drupal創設者が行う、Drupalデプロイワークフローの紹介
最後に
PHPStanの導入そのものはDrupal専用プラグインがあるので結構簡単です。
導入後の継続実行が大事なので運用できるレベル感でぜひあなたのプロジェクトにも導入してみてください。
あとこういう話ができる場所として Drupal Meetup Tokyo があります。
興味を持たれた方はぜひ遊びにきてください!
Drupal