WEB

DockerとPHPStanを使ってPHPのバージョンアップ静的検証をする

PHPのバージョンアップ静的検証がしたい

PHP7のサポートが終了して久しいですが、諸事情により7系を使い続けている人はまだいるのではないでしょうか。いつでもPHP8に対応できるように、非推奨関数やメソッドなどのチェックをしておきたいので考えました。

サーバーを借りて既存のDBやPHPプログラムを置いて検証がスタンダードだと思いますが、いちいち借りるのも面倒なので、Dockerで実践してみます。

1.Dockerで検証環境を構築。

前提環境:ホストマシーン=WSL2+Docker Desktop for Windows

2.「PHPStan」を利用。

検証の際に、無料で使える静的解析ツールPHPStanを使用します。

ファイル構成とDockerの構成

test
 ┣html
  ┣phpstan.neon
  ┗target_program.php
 ┗docer-compose.yml

Dockerの構成をやったことがないので調べ調べやっていきます。必要なものはPHPとPHPStanですが、docker‐compose.ymlやDockerfileに何を書けばいいのかよくわかりません。

php-apacheのDockerイメージと、そこにcomposerでPHPStanを入れるパターンと、PHPStanのDockerイメージ(PHPStanが提供してくれている)のみ入れるパターンが考えられるようです。PHPStanのイメージのが手軽そうなのでこれでいきます。

いつものようにChatGPT先生に聞きながら、Google先生に聞きながらdocker-compose.ymlを試行錯誤しました。

version: '3'

services:
  phpstan:
    image: phpstan/phpstan:latest
    volumes:
      - ./html:/html
    command: analyze /html -c phpstan.neon

docker-compose.yml

PHPStanのDockerイメージで、phpのバージョンの指定をする場合は

公式サイトを参照して試したいphpバージョンのタグを指定します。
※2024年2月現在では以下のタグとなっていました。

  • 11-php8.0latestlatest-php8.0 (PHP 8.0)
  • 1-php8.1latest-php8.1 (PHP 8.1)
  • 1-php8.2latest-php8.2 (PHP 8.2)
  • 1-php8.3latest-php8.3 (PHP 8.3)
  • nightlynightly-php8.0 – latest dev version (PHP 8.0)
  • nightly-php8.1 – latest dev version (PHP 8.1)
  • nightly-php8.2 – latest dev version (PHP 8.2)
  • nightly-php8.3 – latest dev version (PHP 8.3)

注意点:

参考サイトではcommandに「command: analyze」とだけ書いてあったりしましたが、それで実行したらパスを指定しろと怒られます。

phpstan.neonのファイル名も指定します。サンプルサイトなどを見ると、volumeで指定した場所の直下にphpstan.neonを置けば良いように見えましたが、ファイルを直接指定しないとneonに記述した内容が一向に反映されませんでした。私だけなのでしょうか……?

phpstan.neonの設定

phpstan.neon(test.neonでも名前は何でもいいらしい)というファイルを置いて、検証時の細かいパラメータを一括で管理します。

parameters:
    level: 0 # ベースライン
    paths:
        - /html
    parallel:
        processTimeout: 1200.0

phpstan.neon

level:0は無視できない致命的エラーのみを検出するレベルと認識しております。
parallel:に指定したprocessTimeoutはデフォルト50秒なのですが、検査するファイル数とホストマシーンのスペックにもよりますが、500ファイル検索するのに1200秒設定しないとタイムアウトとなりました。

test-phpstan-1  |  -- --------------------------------------------------------------------------- 
test-phpstan-1  |      Error                                                                      
test-phpstan-1  |  -- --------------------------------------------------------------------------- 
test-phpstan-1  |      Reached internal errors count limit of 50, exiting...                      
test-phpstan-1  |      Internal error: Child process timed out after 60.0 seconds. Try making it  
test-phpstan-1  |      longer with parallel.processTimeout setting.                               
test-phpstan-1  |  -- --------------------------------------------------------------------------- 

検証の実施

ファイルが準備できたら、PowerShellなどのターミナルでこのディレクトリ(test)に入り、「docker-compose up」コマンドを実行します。(Docker Desktop for Windowsを立ち上げておきます。)

起動されるとcommandが発動して検証が開始されます。コンソールにひっかかった部分が次々表示されます。(大量検索する場合は「docker-compose up > result.log」とかしてホストマシーンにログを残すと良いです。)

test-phpstan-1  |  ------ -------------------------------------------------------------------- 
test-phpstan-1  |   Line   target_program.php            
test-phpstan-1  |  ------ -------------------------------------------------------------------- 
test-phpstan-1  |   32     Instantiated class XXXXX not found.                           
test-phpstan-1  |           Learn more at https://phpstan.org/user-guide/discovering-symbols  
test-phpstan-1  |  ------ -------------------------------------------------------------------- 

注意事項

Composerを使わずに参照しているライブラリなどがあるとエラーがでまくる

Composerで依存関係を管理せずに、直接参照している自作ライブラリなどは、phpstan.neonの「parameter:」内に「scanFiles:」でファイルを指定するか「scanDirectories:」ディレクトリ指定しないと参照している箇所でNot foundエラーになります。これを指定するとあらかじめこの中を考慮してくれるらしいです。
注)phpstan.neonからみた相対パスで指定しろとマニュアルにはあるのですがそれだとうまく動作せず、ルートからのパスを記述しました。

デフォルトでは拡張子phpしかみてくれない

拡張子php以外のファイルを検証したい場合は、phpsan.neonに「fileExtensions:」を指定して、検証したい拡張子を追加する必要があります。

上記を反映したphpsan.neon例

parameters:
    level: 0 # ベースライン
    paths:
        - /html
    fileExtensions:
        - php
        - inc
    parallel:
        processTimeout: 1200.0
    scanFiles:
        - /html/lib/common/functions.inc
    scanDirectories:
        - /html/lib/service/
        - /html/lib/user

 

まとめ

無料で使えて利用者も多いと思われるのに、意外と情報が少なかったので記事にしてみました。お役に立てれば幸いです。

 

reiko suzuki
OLD SKOOLシステムエンジニア。ねこを撫でながら働いています。