PHP のファイルが静的解析したくなったので、ソースから AST を得る方法を調べてみました。
以前、Eclipse の ASTParser を使う話を書いたことがありましたが、それの PHP 版になります。
今回の作業にあたって、以下のスライドがとても参考になりました。
PHP は 7 になってから内部的に AST が利用されているため、以前よりも AST を得るのは簡単になっています。
既に以下のような extension が提供されているので、いずれかをインストールすれば大丈夫です。
今回はマニュアルが充実している前者のnikic/php-ast を入れてみることにしました。
以下、構築メモになります。
† 準備
基本的には全てマニュアルに書いてあります。
Linux の場合には pecl を使えば簡単ですが、Windows の場合には対応するバイナリを手動で入れる必要があります。
面倒なので XAMPP を使っている場合に設定を自動的に行う bat を組んでみました。
phpast_setup.bat
cd C:\xampp\php\extcurl -s https://frippery.org/files/busybox/busybox.exe --output busybox.execurl https://windows.php.net/downloads/pecl/releases/ast/1.0.1/php_ast-1.0.1-7.3-ts-vc15-x64.zip --output php_ast-1.0.1-7.3-ts-vc15-x64.zipbusybox unzip php_ast-1.0.1-7.3-ts-vc15-x64.zip php_ast.dllbusybox grep extension=php_ast.dll C:\xampp\php\php.ini > nulif %ERRORLEVEL% == 1 ( busybox sed -e "s/^;extension=xsl/;extension=xsl\n\n#php-ast\nextension=php_ast.dll/" < C:\xampp\php\php.ini > C:\xampp\php\php.ini.new move C:\xampp\php\php.ini C:\xampp\php\php.ini.old move C:\xampp\php\php.ini.new C:\xampp\php\php.ini)del busybox.exe php_ast-1.0.1-7.3-ts-vc15-x64.zip
† 動作確認
今回は以下のように結果を単純に JSON に出力するようにしてあります。
種別やフラグをデコードするためには付属の ast_stub.php, util.php の内容が参考になります。
ast_json_dump.php
<?php$code = <<<'EOC'<?php$var = 42;EOC;echo json_encode(ast\parse_code($code, $version=50), JSON_PRETTY_PRINT);/*OUTPUT: { "kind": 132, //AST_STMT_LIST "flags": 0, "lineno": 1, "children": [ { "kind": 517, // AST_ASSIGN "flags": 0, "lineno": 2, "children": { "var": { "kind": 256, // AST_VAR "flags": 0, "lineno": 2, "children": { "name": "var" } }, "expr": 42 } } ]} */