アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

PHP_CodeSnifferで独自コーディングルール


森川です。最近、メインのLet'snoteの増設メモリが壊れつつあり、1日に1度はブルーバックを眺めています。。。そんなこんなで、blogを書きながらPCが落ちないかどうか、ガクガクブルブルなわけですが、PHP_CodeSnifferをさらっと紹介したいと思います。




アシアルではそれほど厳しくコーディングルールを決めているわけではありませんが、コーディングルールを徹底しないといけない環境というのもあるでしょう。(そういう環境があるからPHP_CodeSnifferの需要もあるのですが。。



早速インストールしてみましょう。





# pear install PHP_CodeSniffer-beta


簡単ですね。
続いてサンプルのコードを用意してみましょう。





<?php
/**
 * sample.php
 * PHP_CodeSnifferのテスト用ファイル
 * @author Morikawa Joe
 */

$list = array(
  "a" => 1,
  "b" => 2,
  "c" => 3,
);

// if
if (sample_func(0)) {
  echo "sample\n";
} else if (sample_func(1)) {
  echo "sample sample\n";
}

// foreach
foreach ($list as $key => $val) {
  echo "key\t" . $val . "\n";
}

/**
 * サンプルクラス
 */
class mySample
{
  /**
   * サンプル変数
   */
  var $sample_var;

  /**
   * サンプルメソッド
   */
  public function myMethod()
  {
  }
}

/**
 * サンプル関数
 */
function sample_func($hoge)
{
  return $hoge;
}



これで準備が整いました。コードのチェックはphpcsコマンドを使用します。





 $ phpcs sample.php



エラーが大量に出力されてしまいました。phpcsでは何も指定しない場合は、PEARのコーディング規約が使用されるのに、sample.phpがあまり準拠していないのが原因です。




ここは、コーディングルールを定義してエラーが出ないようにしてみましょう。




まずは、独自のルールを定義するディレクトリを作成しましょう。独自のルールを作成するためのドキュメントもあるので安心です。




まずはディレクトリの作成です。





 $ mkdir -p /usr/local/lib/php/PHP/CodeSniffer/Standards/MyStandard



/usr/local/lib/phpPEARのインストールディレクトリなので適宜読み替えましょう。




さらにドキュメントにあるMyStandardCodingStandard.phpをそのままコピペで作成します。






 $ vi /usr/local/lib/php/PHP/CodeSniffer/Standards/MyStandardCodingStandard.php



ひとつひとつのルールを定義する簡単な方法は、getIncludedSniffs()メソッドを使って他の定義を使う方法です。以下の場合は、タブでのインデントを禁止する方法ですね。






  public function getIncludedSniffs()
  {
    return array(
      'Generic/Sniffs/WhiteSpace/DisallowTabIndentSniff.php',
    );
  }



もう1つ、少し強引ですがPEARのコーディングルールを基本としたコピーを作るのであれば、Sniffsの内容と、getIncludedSniffs()メソッドの内容をPEARのものから拝借してそのまま使用します。そのままコピーするとクラス名がおかしくなっているので、PEARをMyStandardに変更します。




あとはひたすら、エラーを出している部分を修正します。こうやってかなり地道になりますが、修正することで完全に自分流にカスタマイズした定義ファイルを作成することができます。




PEAR準拠でコーディングしている場合は、楽ですが、独自のコーディングルールを使用している場合は定義するのがかなり大変そうです。もっと楽に定義する方法はあるのだろうか??