phpmdでコード解析+チェックルールのカスタマイズしてみる
前回のphpcsに続きコーディングの品質向上のためphpmdを使うようにしてみました。
phpmdは潜在的にバグになりそうなコードや改善の余地があるコードなどを検出してくれるツールです
phpmdインストール
公式通り、composer.json
に下記を追記してcomposer installします
{ "require-dev": { "phpmd/phpmd" : "*" } }
使い方
コマンドラインで実行する際は下記のように実行できます。
phpmd /path/to/file xml codesize,naming,cleancode
xml以後のオプションで検出ルールを指定します。
ルールが設定してあるxmlはvendor/phpmd/phpmd/src/main/resources/rulesets/
以下にあります。
デフォルトでは下記があります。
またそれぞれのルールの実装はvendor/phpmd/phpmd/src/main/php/PHPMD/Rule/
にあります。
なので、ルールのカスタマイズするには、新規にruleを定義したxmlを作成して、それに対するチェックの実装を行っていく感じになります。
カスタマイズルールを作ってみる
今回はtypoチェックを実装してみました。
まずカスタマイズルール用にxmlを作ります。
vi vendor/phpmd/phpmd/src/main/resources/rulesets/myStandard.xml <?xml version="1.0"?> <ruleset name="My Standard Rules"> <description> This ruleset contains a my standard rules. </description> <rule name="CheckTypo" since="0.2" message = "Maybe typo. {0} : {1} -> {2}" class="PHPMD\Rule\MyStandard\CheckTypo" externalInfoUrl="#"> <description> <![CDATA[ Maybe typo. ]]> </description> <priority>1</priority> <properties /> <example> <![CDATA[ protocal->protocol recompence->recompense ]]> </example> </rule> </ruleset>
上記のように定義して、PHPMD\Rule\MyStandard\CheckTypo
にチェックルールの実装を行っていきます。
typo例はこちらのものを参考としました。
Wikipedia:Lists of common misspellings/For machines - Wikipedia, the free encyclopedia
既存の実装を元に下記のように実装してみました。
./resources/typoList.csv
にtypo単語リストを置いています
vendor/phpmd/phpmd/src/main/php/PHPMD/Rule/MyStandard/CheckTypo.php namespace PHPMD\Rule\MyStandard; use PHPMD\AbstractNode; use PHPMD\AbstractRule; use PHPMD\Rule\FunctionAware; use PHPMD\Rule\MethodAware; /** * This rule CheckTypo. * typo check * */ class CheckTypo extends AbstractRule implements MethodAware, FunctionAware { private static $typoList = []; /** * This method checks typo * * @param \PHPMD\AbstractNode $node * @return void */ public function apply(AbstractNode $node) { $typoList = $this->getTypoList(); foreach ($node->findChildrenOfType('Variable') as $variable) { $image = $variable->getImage(); foreach ($typoList as $key => $value) { if (preg_match("/$key/", $image)) { $this->addViolation($variable, array($image, $key, $value)); break; } } } } /** * get typoList * @return void */ public function getTypoList() { if (self::$typoList) { return self::$typoList; } $typoList = []; $fp = fopen(dirname(__FILE__) . "/resources/typoList.csv", "r"); while (!feof($fp)) { $tmpArr = fgetcsv($fp); $typoList[$tmpArr[0]] = $tmpArr[1]; } self::$typoList = $typoList; fclose($fp); return self::$typoList; } }
実行はこんな感じで、
phpmd /path/to/file xml myStandard
既存の実装を元になんとなくやってみましたが、変数名のtypo検出ができました!
こんな感じでカスタマイズルールを実装することでプロジェクト共通で品質向上やレビューの負荷軽減等していけたらと思いますん。