PHP_CodeSniffer で使用する規約は、すべてコーディング規約に従っている必要があります。 この規約とは、PHP_CodeSniffer ディレクトリ配下にある単一のクラスでなければならないということです。 というわけなので、非常に簡単に作成することができます。 今回作成するコーディング規約は MyStandard という名前にしましょう。次のコマンドで、このコーディング規約用のディレクトリ構造を作成します。
$ cd /path/to/PHP_CodeSniffer/CodeSniffer/Standards
$ mkdir MyStandard
$ mkdir MyStandard/Sniffs
|
MyStandard ディレクトリが 今回作成するコーディング規約そのものを表し、 チェック時にコマンドラインで指定するときには、このディレクトリ名を使用します。 サブディレクトリ Sniffs には、 このコーディング規約が使用するすべての sniff ファイルを保存します。
ディレクトリ構造ができたので、クラスファイルを追加していきましょう。 このファイルによって PHP_CodeSniffer がコーディング規約の情報を問い合わせられるようになり、 このディレクトリが sniff を含むものであることを示します。
$ cd /path/to/PHP_CodeSniffer/CodeSniffer/Standards/MyStandard
$ touch MyStandardCodingStandard.php
|
MyStandardCodingStandard.php ファイルの内容は、 次のようになります。
<?php
/**
* MyStandard コーディング規約
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author あなたの名前 <you@domain.net>
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @version CVS: $Id: coding-standard-tutorial.xml,v 1.7 2007/10/21 00:47:28 takagi Exp $
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
require_once 'PHP/CodeSniffer/Standards/CodingStandard.php';
/**
* MyStandard コーディング規約
*
* @category PHP
* @package PHP_CodeSniffer
* @author あなたの名前 <you@domain.net>
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @version Release: @package_version@
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class PHP_CodeSniffer_Standards_MyStandard_MyStandardCodingStandard extends PHP_CodeSniffer_Standards_CodingStandard
{
}//end class
?> |
注意 コーディング規約クラスは、この例のように空のままにしておくこともできます。 オーバーライドできるメソッドについての情報は、 コーディング規約クラスについてのドキュメント を参照ください。
各 sniff は、それぞれ個別の PHP ファイルを使用します。 その名前は、扱っている規約の内容がはっきりわかるようなものにします。 また、名前の最後は Sniff.php としなければなりません。 今回の場合は、PHP のファイル名は DisalowHashCommentsSniff.php とし、サブディレクトリ Commenting に配置します。 これにより、この規約がコメントに関するものであることを表しています。 以下のコマンドで、カテゴリおよび sniff ファイルを作成します。
$ cd /path/to/PHP_CodeSniffer/CodeSniffer/Standards/MyStandard/Sniffs
$ mkdir Commenting
$ touch Commenting/DisallowHashCommentsSniff.php
|
注意 カテゴリ分けにどんなサブディレクトリを使用するかは決まっていません。 わかりやすい名前にしておき、あとで修正する際にそれを見つけやすいようにしておきましょう。
各 sniff ファイルは PHP_CodeSniffer_Sniff インターフェイスを実装している必要があります。これにより、 PHP_CodeSniffer はそれが sniff であることを知り、 起動時にインスタンスを作成します。 PHP_CodeSniffer_Sniff で定義されているメソッドは register() および process() のふたつで、これらは必ず実装しなければなりません。
register() メソッドでは、 処理の対象となるトークンの型を sniff に登録します。 PHP_CodeSniffer がこれらのトークンに遭遇すると、 PHP_CodeSniffer_File オブジェクト (現在チェック中のファイルを表します) およびスタック内でそのトークンが見つかった位置を指定して process() メソッドをコールします。
今回作成する sniff で対象としているのは、単一行コメントです。PHP_CodeSniffer がトークンの取得に使用している token_get_all() メソッドは、doc コメントと通常のコメントを別のトークン型として判定します。 そこで、doc コメントは今回のテストでは気にしないことにします。 register() メソッドは、単一のトークン型 T_COMMENT を返すようにする必要があります。
sniff は、トークンに関するより多くの情報を取得するためにトークンスタックを使用することができます。 そのためには、PHP_CodeSniffer_File オブジェクトの getTokens() メソッドをコールします。 このメソッドは配列を返します。そのインデックスが、 トークンスタック内でのトークンの現れる位置を表します。 配列の各要素が、トークンを表します。 すべてのトークンは配列形式で、 code、type および content というインデックスを持っています。 code の値は、トークンの型を表す一意な整数値です。 type の値は、トークンの型を表す文字列です (たとえば 'T_COMMENT' はコメントトークンを表します)。 type は、その名前に対応するグローバルに定義された整数値も保持します。 また、content の値には、 コード内で現れたトークンの内容が含まれます。
注意 トークンによっては、上で説明したもの以外のインデックスを持っているものもあります。 PHP/CodeSniffer/File.php クラスのコメントで、 トークンの一覧とそのインデックスを参照ください。
では、sniff の中身を書いていきましょう。 DisallowHashCommentsSniff.php ファイルの内容は、次のようになります。
<?php
/**
* PHP_CodeSniffer tokenises PHP code and detects violations of a
* defined set of coding standards.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Your Name <you@domain.net>
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @version CVS: $Id: coding-standard-tutorial.xml,v 1.7 2007/10/21 00:47:28 takagi Exp $
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
require_once 'PHP/CodeSniffer/Sniff.php';
/**
* This sniff prohibits the use of Perl style hash comments.
*
* An example of a hash comment is:
*
* <code>
* # This is a hash comment, which is prohibited.
* $hello = 'hello';
* </code>
*
* @category PHP
* @package PHP_CodeSniffer
* @author Your Name <you@domain.net>
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @version Release: @package_version@
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class MyStandard_Sniffs_Commenting_DisallowHashCommentsSniff implements PHP_CodeSniffer_Sniff
{
/**
* Returns the token types that this sniff is interested in.
*
* @return array(int)
*/
public function register()
{
return array(T_COMMENT);
}//end register()
/**
* Processes the tokens that this sniff is interested in.
*
* @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
* @param int $stackPtr The position in the stack where
* the token was found.
*
* @return void
*/
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
if ($tokens[$stackPtr]['content']{0} === '#') {
$error = 'Hash comments are prohibited';
$phpcsFile->addError($error, $stackPtr);
}
}//end process()
}//end class
?> |
これでコーディング規約が定義できたので、 ハッシュ形式のコメントを含むファイルの検証をしてみましょう。
ここでは次のような内容のテストファイルを使用するものとします。
<?php
# Check for valid contents.
if ($obj->contentsAreValid($array)) {
$value = $obj->getValue();
# Value needs to be an array.
if (is_array($value) === false) {
# Error.
$obj->throwError();
exit();
}
}
?> |
PHP_CodeSniffer を実行してこのファイルを新たなコーディング規約でチェックすると、 3 つのエラーが発生します。
$ phpcs --standard=MyStandard Test.php FILE: Test.php -------------------------------------------------------------------------------- FOUND 3 ERROR(S) AND 1 WARNING(S) AFFECTING 3 LINE(S) -------------------------------------------------------------------------------- 3 | ERROR | Hash comments are prohibited 7 | ERROR | Hash comments are prohibited 9 | ERROR | Hash comments are prohibited -------------------------------------------------------------------------------- |