LoginSignup
91
102

More than 5 years have passed since last update.

PHPの静的解析いろいろ

Posted at

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を指定します。

PSR-2でチェック実行
$ 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の場合は、プロジェクトルートに以下のようなファイルを配置して、プラグインの設定画面にファイル名を入力します。ルールは除外したり、独自の設定値で上書き可能です。

phpmd.xml
<?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さんが作ったようです。

インストール

macにインストール
brew update
brew install php70 php70-ast phan

設定ファイルを用意

プロジェクトルートに .phan/config.php を作成します。

config.php
<?php

return [

    'directory_list' => [
        'app',
    ],

    "exclude_analysis_directory_list" => [
        'vendor'
    ],
];

directory_list は解析対象のディレクトリのリストで、 exclude_analysis_directory_list に定義されたディレクトリを除外した後、残りのファイルは静的にエラーを分析されます。

実行

実行
$ phan -ophan.log
phan.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 はもう少し追ってみようと思います。

91
102
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
91
102