🔍

【PHP】Phan + Dockerを使用した下方互換性のない変更点の検出

2021/08/28に公開

概要

PHP の静的検証ツールである Phan と Docker を使用して、 PHP のバージョン間の下方互換性のない変更点を検出する方法です。

Phan

PHP 静的検証ツールです。
https://github.com/phan/phan

実行環境構築

環境

phanphp/phan

Phan の Docker イメージです。公式ドキュメントにて紹介されいるもので今回はこれを使用します。
https://github.com/phan/docker

ディレクトリ構造

.
├ src/
│ └ .phan/config.php
│ └ index.php
├ log/
└ docker-compose.yml
  • src下に Phan の設定ファイルである.phan/config.phpと解析したいファイルを配置します。今回はindex.phpを解析します。
  • logディレクトリに Phan の解析結果を出力するようにします。

docker-compose.yml

version: "3"

services:
  phan:
    image: phanphp/phan:latest
    volumes:
      - ./src:/mnt/src
      - ./log:/mnt/log

.phan/config.php

.phan/config.phpには Phan の設定を記載します。
設定内容については公式ドキュメントを参考にしてください。
今回は公式ドキュメントにある下方互換性の設定項目を参考にした設定内容となります。

<?php
return [
    'directory_list' => [
        './'
    ],
    'backward_compatibility_checks' => true,
    'ignore_undeclared_functions_with_known_signatures' => false,
    'whitelist_issue_types' => [
        'PhanCompatiblePHP7',  // 変更された可能背のある構文のチェック
        'PhanDeprecatedFunctionInternal',  // 7.0移行で非推奨になった関数についての警告
        'PhanUndeclaredFunction',  // PHP5.xで非推奨になり、PHP7.0で削除された関数の確認
    ],
    'plugins' => ['InvokePHPNativeSyntaxCheckPlugin'],
];
?>

index.php

今回はindex.phpにあるコードを解析していきたいと思います。
このコードは公式ドキュメントにある下方互換性の設定項目内にあるコードを引用しています。

<?php
echo $foo->$bar['baz'];
Foo::$bar['baz']();
$foo->$bar['baz']();
strlen($foo->$bar['baz']);
class C {
    public $bb = 2;
}
class T {
    public $b = null;
    function fn($a) {
      $this->b = new C;
      echo $this->b->$a[1];
    }
}
$t = new T;
$t->fn(['aa','bb','cc']);
class Test {
    public static $vals = array('a' => 'A', 'b' => 'B');
    public static function get($letter) {
        return self::$vals[$letter];
    }
	public function fn($letter) {
        return $this->vals[$letter];
    }
}
?>

実行

docker-compose run phan -po /mnt/log/analysis.txtを実行します。
解析結果はlogディレクトリ下のanalysis.txtに出力されます。
今回の解析で検出された問題は以下となります。

index.php:2 PhanCompatiblePHP7 Expression may not be PHP 7 compatible
index.php:3 PhanCompatiblePHP7 Expression may not be PHP 7 compatible
index.php:4 PhanCompatiblePHP7 Expression may not be PHP 7 compatible
index.php:5 PhanCompatiblePHP7 Expression may not be PHP 7 compatible
index.php:13 PhanCompatiblePHP7 Expression may not be PHP 7 compatible

参考文献

phan/docker
Using Phan
Just Backward Compatibility
面倒いの抜きで PHP の静的解析「Phan」を使ってみる with Docker

Discussion