php phpdcd (Dead Code Detector)を試してみた

 2011/03/28
このエントリーをはてなブックマークに追加

phpdcdはPHP Dead Code Detector という名の通り、使っていないコードを検出してくれるツールである。

ウノウラボさんのPHPで利用出来るテストと開発に便利なツールで知ったので評価してみた。

なお、Dead CodeについてはWikiPediaのこのページが詳しい。

インストール

普通にpearコマンドでインストールできる。 ``` pear channel-discover pear.phpunit.de pear channel-discover components.ez.no pear update-channels pear install phpunit/phpdcd ``` 以上でインストールが完了する。

実行

まずは引数なしで実行してみよう。オプションが分かる。(--helpを付けたときと同じ) ``` [root@CI01 ryuzee]# phpdcd phpdcd 0.9.2 by Sebastian Bergmann. Usage: phpdcd [switches] <directory|file> ... --recursive Report code as dead if it is only called by dead code. --exclude <dir> Exclude <dir> from code analysis. --suffixes <suffix> A comma-separated list of file suffixes to check. --help Prints this usage information. --version Prints the version and exits. --verbose Print progress bar. ``` では試してみよう。

サンプル1:超シンプル版

1つのコードの中でのDeadコードを探してみよう。ということでテスト対象のソース。 dcdsample0.php ``` class DcdSample { function func1() { echo "func1\n"; } } $foobar = ""; $foobar = "hoge"; echo "foobar\n"; ``` ではdcdを実行 ``` phpdcd --verbose dcdsample0.php ``` 出力結果 ``` phpdcd 0.9.2 by Sebastian Bergmann. Processing files 1 / 1 [+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>] 100.00% - DcdSample::func1() declared in dcdsample0.php:4 ``` * ClassのDcdSampleはどこからもインスタンスが作られていないのでDeadコード * $foobarの代入はどこでも使われていないけど、変数の代入やメンバー変数の宣言等はDeadコードの対象にはなっていない。あくまで関数やクラスレベルでの検出(=冗長コードの検出であり、冗長宣言の検出ではない)のようだ。

サンプル2:既存アプリケーションにかけてみようか

CakePHPで作ったアプリケーションのコントローラにかけてみた。 オチが読めるかもしれないが、CakePHPのアプリケーションにおいては、フロントエンドDispatcherが、コントローラーのどのメソッドを実行するかをURLをベースにして決めているので、通常、ソースコードの中には明示的にメソッドの呼び出しを行っている箇所が存在しない。従ってこういう結果になる。こりゃ意味が無いかも。 ``` phpdcd 0.9.2 by Sebastian Bergmann. Processing files 1 / 1 [+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>] 100.00% - UsersController::admin_add() declared in users_controller.php:187 - UsersController::admin_delete() declared in users_controller.php:262 - UsersController::admin_edit() declared in users_controller.php:221 - UsersController::admin_index() declared in users_controller.php:160 - UsersController::admin_view() declared in users_controller.php:173 - UsersController::beforeFilter() declared in users_controller.php:41 - UsersController::edit() declared in users_controller.php:122 - UsersController::index() declared in users_controller.php:111 - UsersController::login() declared in users_controller.php:75 - UsersController::logout() declared in users_controller.php:98 ```

サンプル3:ということで

以下のソースは、今度はクラスのインスタンスを生成しているので、全てのコードを通っているんだけど、インスタンスの生成の際にクラス名を変数で記述しているので、phpdcdは正しく解釈できない。 ``` class DcdSample { function func1() { echo "func1\n"; } } $class = "DcdSample"; $obj = new $class(); $obj->func1(); ``` 結果はこうなる。結果だけ見てこのクラスを消すと事件が起きる。 ``` phpdcd 0.9.2 by Sebastian Bergmann. - DcdSample::func1() declared in dcdsample3.php:4 ```

結論

バッチ処理みたいに頭から逐次実行されるような奴なら結果の精度は高いかもしれないが、フレームワークを使ったWebアプリケーションではちょっと厳しい。 個人的には使わないし、使ったら危ないんじゃないの?という気がする。

代替のソリューション

Deadコードを探してソースをクリーンに保つ他の方法としては、自動テストによってカバレージを取得し、カバーしていない箇所を丹念に見ていくといった方策のほうが安心感があると思う。(但しカバレージは数値そのものを目標にはしないので、当然ながらテストによってカバーされていないがアプリケーション内で利用されているコードは存在する。一般的にはカバレージは80%〜90%くらいであることが多い。)

もちろんコードを削除することによってアプリケーションに影響が出ないことは自動テストによって担保すべきである。

また、利用されていないコードについてはペアプロやコードレビューによっても早期に発見されるべきで、最後にあわててツールを使って消すようなものでもない。 日々コードをクリーンに保つ、という意識がないとツールを使った帳尻合わせになってしまいかねない。

 2011/03/28
このエントリーをはてなブックマークに追加

サイト内検索


著作

寄稿

Latest post: