Atomエディタをよく使っているのですが、phpmdプラグインがStaticAccessのエラーを出すのを止めたくて調べ始めたところ、こちらのページで静的解析ツールがいろいろとあることを知ったので、いくつか試してみました。
Atomのプラグインでダウンロードが多そうなもの
まずはAtomのLinterでよく使われていそうなものから。
インストール方法は各URLを参照してください。
PHP lint
PHP標準のシンタックスチェック機能です。
構文に誤りがないかのチェックのみなので、ひどいコードでもパスします。
php -l <filenmae>
プラグイン
https://atom.io/packages/linter-php
phpcs
PHP Code Snifer
https://github.com/squizlabs/PHP_CodeSniffer
指定したコーディングスタンダードに適合しているかをチェックします。
プラグイン
https://atom.io/packages/linter-phpcs
$ phpcs -i
The installed coding standards are MySource, PEAR, PHPCS, PSR1, PSR2, Squiz and Zend
デフォルトはPEARのようなので、PSR2を指定します。
$ phpcs --standard=PSR2 Illuminate/Auth/AuthServiceProvider.php
FILE: ...or/laravel/framework/src/Illuminate/Auth/AuthServiceProvider.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
57 | ERROR | [x] Only one argument is allowed per line in a
| | multi-line function call
----------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------
Time: 210ms; Memory: 4Mb
phpmd
PHP Mess Detection
https://phpmd.org/documentation/creating-a-ruleset.html
考えられるバグ、最適でないコード、複雑すぎる表現、未使用のパラメータ・メソッド・プロパティ等の潜在的な問題を検出します。
プラグイン
https://atom.io/packages/linter-phpmd
ここに書かれているルールの中からチェックしたいものを指定して実行します。
$ phpmd wp-login.php text codesize
/path/to/wordpress/wp-login.php:33 The function login_header() has a Cyclomatic Complexity of 20. The configured cyclomatic complexity threshold is 10.
/path/to/wordpress/wp-login.php:33 The function login_header() has an NPath complexity of 52224. The configured NPath complexity threshold is 200.
/path/to/wordpress/wp-login.php:33 The function login_header() has 175 lines of code. Current threshold is set to 100. Avoid really long methods.
/path/to/wordpress/wp-login.php:278 The function retrieve_password() has a Cyclomatic Complexity of 10. The configured cyclomatic complexity threshold is 10.
Atomの場合は、プロジェクトルートに以下のようなファイルを配置して、プラグインの設定画面にファイル名を入力します。ルールは除外したり、独自の設定値で上書き可能です。
<?xml version="1.0"?>
<ruleset name="My PHPMD rule set"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0
http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="
http://pmd.sf.net/ruleset_xml_schema.xsd">
<rule ref="rulesets/cleancode.xml">
<exclude name="StaticAccess" />
</rule>
<rule ref="rulesets/codesize.xml" />
<rule ref="rulesets/controversial.xml" />
<rule ref="rulesets/design.xml" />
<rule ref="rulesets/naming.xml" />
<rule ref="rulesets/unusedcode.xml" />
</ruleset>
php7cc
PHP 7 Compatibility Checker
https://github.com/sstalle/php7cc
コードがPHP7に対応しているかをチェックするツールです。
プラグイン
https://atom.io/packages/linter-php7cc
$ php7cc wp-includes/
File: /path/to/wordpress/wp-includes/atomlib.php
> Line 162: Removed function "split" called
split(':', $name);
> Line 241: Removed function "split" called
split(':', $name);
> Line 316: Removed function "split" called
split(':', $qname);
File: /path/to/wordpress/wp-includes/capabilities.php
> Line 429: Function argument(s) returned by "func_get_args" might have been modified
func_get_args();
> Line 456: Function argument(s) returned by "func_get_args" might have been modified
func_get_args();
> Line 486: Function argument(s) returned by "func_get_args" might have been modified
func_get_args();
> Line 508: Function argument(s) returned by "func_get_args" might have been modified
func_get_args();
:
Githubでスターが多いもの
ここからはスターが多かったものを見てみます。
phan
PHPの生みの親、Rasmusさんが作ったようです。
インストール
brew update
brew install php70 php70-ast phan
設定ファイルを用意
プロジェクトルートに .phan/config.php
を作成します。
<?php
return [
'directory_list' => [
'app',
],
"exclude_analysis_directory_list" => [
'vendor'
],
];
directory_list
は解析対象のディレクトリのリストで、 exclude_analysis_directory_list
に定義されたディレクトリを除外した後、残りのファイルは静的にエラーを分析されます。
実行
$ phan -ophan.log
:
app/Http/Controllers/BaseController.php:10 PhanUndeclaredTypeParameter Parameter of undeclared type \Illuminate\Http\Request
app/Http/Controllers/BaseController.php:12 PhanUndeclaredProperty Reference to undeclared property request
app/Http/Controllers/BaseController.php:13 PhanUndeclaredClassMethod Call to method getMonolog from undeclared class \Log
app/Http/Controllers/BaseController.php:14 PhanUndeclaredClassMethod Call to method __construct from undeclared class \Monolog\Processor\IntrospectionProcessor
:
もう少し設定の余地がありそうな結果となりました。 config.php で詳細な設定が可能なようです。
その他
型のアノテーションを記述することで、より正確に解析を行うことができるようです
class C
/** @var int */
const C = 42;
また、PHP7へ移行する際の互換性チェックも可能です。
ここを参照してください。
pfff
Facebook製のコード解析、ビジュアライズ、style-preserving source transformation(スタイルを保ったソースコードの変換??フォーマットのことかな)が可能で、PHP以外にも多くの言語に対応しているようです。
ただインストールが激ムズで、makeが通らなくて断念しました。。。
phpcpd
Copy/Paste Detector
https://github.com/sebastianbergmann/phpcpd
名前のとおり、重複したコードを検知可能なツールです。
$ composer require "sebastian/phpcpd=*" --dev
$ phpcpd wp-includes/class-snoopy.php
phpcpd 2.0.4 by Sebastian Bergmann.
Found 4 exact clones with 125 duplicated lines in 1 files:
- /wp-includes/class-snoopy.php:165-195
/wp-includes/class-snoopy.php:225-255
- /wp-includes/class-snoopy.php:133-155
/wp-includes/class-snoopy.php:285-307
- /wp-includes/class-snoopy.php:181-218
/wp-includes/class-snoopy.php:339-376
- /wp-includes/class-snoopy.php:317-353
/wp-includes/class-snoopy.php:384-420
9.95% duplicated lines out of 1256 total lines of code.
Time: 28 ms, Memory: 6.00MB
phpsa
Smart Analyzer for PHP
https://github.com/ovr/phpsa
「複雑な分析を目的とした」ツールで、JetBrain社がスポンサー?のようです。
まだ early alpha state
とのこと。
$ composer require "ovr/phpsa" --dev
$ vendor/bin/phpsa check app/Http/Controllers/Auth/
Scanning directory app/Http/Controllers/Auth/
Found 4 files
Notice: Missing Docblock in app/Http/Controllers/Auth/ForgotPasswordController.php on 8 [missing_docblock]
class ForgotPasswordController extends Controller
Notice: Missing Docblock in app/Http/Controllers/Auth/LoginController.php on 8 [missing_docblock]
class LoginController extends Controller
Notice: Missing Docblock in app/Http/Controllers/Auth/RegisterController.php on 10 [missing_docblock]
class RegisterController extends Controller
終わりに
個人的には phpcs と phpmd をメインに、PHP7に移行する際は php7cc を使ってみます。
phan はもう少し追ってみようと思います。