miau's blog?

PHP_CodeSniffer の --standard オプション比較

上流の会社が最近 PHP_CodeSniffer によるスタイルのチェックを推奨しているらしい。そんなもので縛らなくてもまともなコード書ける人ばかりだといいんだけど・・・うちでもたまにひどい人がいるから文句言えない。(平気で 8 タブでインデントするような人もいたし。見たとき眩暈がした・・・。)

PHP_CodeSniffer では自分でコーディングスタイルの基準を定義したりもできるんだけど、組み込みの基準も何種類かあったりする。その基準で PEAR と Zend 以外に言及してる人が少なかったから、まずはそこについて触れておこうかと。




■インストール

>pear install PHP_CodeSniffer-1.1.0RC1

ということで、今回は現時点で最新版である 1.1.0 RC1 で確認してます。

■--standard オプションについての概要

phpcs を -i オプションつきで実行すると、インストールされているコーディング規約の一覧が取得できる。

>phpcs -i
The installed coding standards are MySource, PEAR, PHPCS, Squiz and Zend

PEAR と Zend は想像つくからいいとして・・・残りの 3 つ何さ?

今回は CakePHP の案件なので、

PHP_CodeSnifferを試してみる | Shin x blog

にならって cake/dispatcher.php を対象にそれぞれのオプションで phpcs を実行して、動作を比較してみた。
ちなみに CakePHP のソースははタブでインデントされているみたいなので --tab-width=4 をつけて実行。これつけないと「Spaces must be used to indent lines; tabs are not allowed」がたくさん出てきて鬱陶しい。

説明しやすい順に書いてみる。

■Squiz

クラスのコメントによると、

The Squiz standard uses some generic sniffs, and also borrows from the
the PEAR standard.

だそうな。Squiz ってのは PHP_CodeSniffer の中の人が勤めてる会社のことみたい。(PHP_CodeSniffer の copyright も「Squiz Pty Ltd」になってる。)

>phpcs -v --tab-width=4 --standard=Squiz dispatcher.php
Registering sniffs in Squiz standard... DONE (91 sniffs registered)
Processing dispatcher.php [6089 tokens in 720 lines]... DONE in 2 seconds (843 errors, 46 warnings)

FILE: D:\xampp\cake_1.2.0.6311-beta\cake_1.2.0.6311-beta\cake\dispatcher.php
--------------------------------------------------------------------------------
FOUND 843 ERROR(S) AND 46 WARNING(S) AFFECTING 436 LINE(S)

後述の PEAR や Zend に比べると結構厳しいチェックになっている。いくつか抜き出すと、こんな感じ。

2 | ERROR | Single line block comment not allowed; use inline ("// text")
| | comment instead

単一行のコメントではブロックコメント使っちゃダメだとか、

44 | ERROR | First line of comment not aligned correctly; expected 4 spaces
| | but found 1
44 | ERROR | Block comments must start with a capital letter

↓こんな形式のコメントにケチつけたりとか。この書き方は別に悪くないと思うんだけど。

/**
* Base URL
*
* @var string
* @access public
*/


■MySource


The MySource standard is an extension of the Squiz standard, with
specific tests for the MySource CMS, so include the whole Squiz standard.

だそうで、Squiz を MySource CMS 用にカスタマイズしたものだそうな。

>phpcs -v --tab-width=4 --standard=MySource dispatcher.php
Registering sniffs in MySource standard... DONE (99 sniffs registered)
Processing dispatcher.php [6089 tokens in 720 lines]... DONE in 2 seconds (874 errors, 54 warnings)

FILE: D:\xampp\cake_1.2.0.6311-beta\cake_1.2.0.6311-beta\cake\dispatcher.php
--------------------------------------------------------------------------------
FOUND 874 ERROR(S) AND 54 WARNING(S) AFFECTING 451 LINE(S)

ってことで、Squiz よりもエラーとみなされるものが増えている。内容を見てみると・・・

33 | ERROR | Static method called on non-included class or system "App";
| | include system with Channels::includeSystem() or include class
| | with require_once

完全に独自ルール。プロジェクト外の人が使うことはまずないと思うんだけど「せっかく作ったんだし配布物に含めちゃえ」くらいのノリなのかな。まあプロジェクトごとに独自ルール設定する場合のサンプルにはなるかも。

■PHPCS


The PHP_CodeSniffer standard combines the PEAR and Squiz standards
but removes some sniffs from the Squiz standard that clash with
those in the PEAR standard.

PEAR と Squiz のあいのこ(ルールがかちあった場合は PEAR 優先)と。

>phpcs -v --tab-width=4 --standard=PHPCS dispatcher.php
Registering sniffs in PHPCS standard... DONE (103 sniffs registered)
Processing dispatcher.php [6089 tokens in 720 lines]... DONE in 2 seconds (712 errors, 39 warnings)

FILE: D:\xampp\cake_1.2.0.6311-beta\cake_1.2.0.6311-beta\cake\dispatcher.php
--------------------------------------------------------------------------------
FOUND 712 ERROR(S) AND 39 WARNING(S) AFFECTING 402 LINE(S)

ま、Squiz ほどは厳しくない感じ。具体例は Squiz や PEAR の項に書いてるので省略。

■PEAR

クラスのコメントにはちゃんと書かれてないけど、これに準拠してるんだと思う。

PEAR :: Manual :: Coding Standards

>phpcs -v --tab-width=4 --standard=PEAR dispatcher.php
Registering sniffs in PEAR standard... DONE (24 sniffs registered)
Processing dispatcher.php [6089 tokens in 720 lines]... DONE in 2 seconds (182 errors, 65 warnings)

FILE: D:\xampp\cake_1.2.0.6311-beta\cake_1.2.0.6311-beta\cake\dispatcher.php
--------------------------------------------------------------------------------
FOUND 182 ERROR(S) AND 65 WARNING(S) AFFECTING 208 LINE(S)

ということで、Squiz ほど厳しくはない。

39 | ERROR | Package name "cake" is not valid; consider "Cake" instead
39 | ERROR | @package tag comment indented incorrectly. Expected 4 spaces
| | but found 5.
40 | ERROR | Subpackage name "cake.cake" is not valid; consider "Cake.cake"
| | instead
40 | ERROR | @subpackage tag comment indented incorrectly. Expected 1 spaces
| | but found 2.
41 | ERROR | Missing @category tag in class comment
41 | ERROR | Missing @author tag in class comment
41 | ERROR | Missing @license tag in class comment
41 | ERROR | Missing @link tag in class comment

ということで、PEAR のルールに従ってない phpDocumentor のコメントはエラー扱い。pear.php.net で公開する上でのルールってことになると思うんだけど、仕事で使うソース(発注元に納品したらそれでおしまい)には必要なさそうな項目もあるな。

43 | ERROR | Line indented incorrectly; expected at least 4 spaces, found 0
44 | ERROR | Line indented incorrectly; expected at least 4 spaces, found 1
:

これは、

class Dispatcher extends Object {
/**
* Base URL
*
* @var string
* @access public
*/

こういう風にコメントがインデントに従っていない場合に警告されているみたい。これだと IDE の機能でコメントアウトした場合に問題になったりしそうだなぁ。まあ最終的にコミットするタイミングではコメントアウト外すだろうから、問題にはなりにくいかな。

125 | WARNING | Equals sign not aligned with surrounding assignments; expected

これが結構問題なやつ。愚痴ってるとちょっと長くなりそうなので、次項で個別に書こうかと。

■Zend

これもクラスのコメントにちゃんと書かれてないけど、

ZF Coding Standards (RC) - Zend Framework Wiki

これを基準にチェックするってことだと思う。

>phpcs -v --tab-width=4 --standard=Zend dispatcher.php
Registering sniffs in Zend standard... DONE (14 sniffs registered)
Processing dispatcher.php [6089 tokens in 720 lines]... DONE in 1 second (17 errors, 28 warnings)

FILE: D:\xampp\cake_1.2.0.6311-beta\cake_1.2.0.6311-beta\cake\dispatcher.php
--------------------------------------------------------------------------------
FOUND 17 ERROR(S) AND 28 WARNING(S) AFFECTING 45 LINE(S)

ということで、チェックとしては一番緩い感じ。

21 | WARNING | Line exceeds 80 characters; contains 95 characters
42 | ERROR | Opening brace of a class must be on the line after the
| | definition
106 | ERROR | Line exceeds maximum limit of 120 characters; contains 139
| | characters

ということで、ある程度納得のいく項目にしか文句が言われていない。個人的にはこれが一番好きかなぁ。

一行あたりの文字数制限についてはちょっと悩むところなんだけど、PHP は

class PHP_CodeSniffer_Standards_Zend_ZendCodingStandard extends PHP_CodeSniffer_Standards_CodingStandard

みたいにクラス名が長くなりがちだから、こんなの守るの無理だよねぇ。早めに namespace 導入してればクラスの命名規則をもっとましにできただろうに。

↓は似たようなことに言及してる blog。throw のときも文字数制限はきついですよね。

GANCHIKU.com » PHP_CodeSnifferいいお。

■Zend + Zend Code Analyzer

--standard=Zend は Zend Code Analyzer ってのを入れておくと追加のチェックもやってくれる。入手法は次項で書くとして、検出結果として増えていたのは以下のようなもの。

104 | WARNING | Function '__construct' has both empty return and return with
| | value.

147 | WARNING | Variable 'missingView' encountered only once. May be a typo?
147 | WARNING | Value assigned to variable 'missingView' is never used

550 | WARNING | Assignment seen where boolean expression is expected. Did you
| | mean '==' instead of '='?

確かに気になる部分の指摘。コーディングスタイルだけじゃなくて、C でいう lint レベルの(品質に関わる部分の)チェックもやってくれるわけね。これは他のオプションではチェックできない WARNING なので導入の価値はあるな。

401 | WARNING | Variable 'base' is used before it was assigned.

693 | WARNING | include/require with user-accessible variable can be dangerous.
| | Consider using constant instead.

こんな WARNING も出てたけど、これは対象が dispatcher.php だから特殊な処理が必要なだけで、普通の処理が対象なら大丈夫だと思う。


ということでとりあえず比較は終わり。次回も PHP_CodeSniffer について書き損ねた諸々について書く予定。

→書きました。

PHP_CodeSniffer のつづき - miau's blog?


(2008-06-26 追記)

Zend Code Analyzer が使えるのは Zend だけ、みたいな書き方してしまったけど、このチェックを実際に行っているのは Zend/Sniffs/Debug/CodeAnalyzerSniff.php のようで。つまり getIncludedSniffs() にこのファイルへの参照を追加してやれば、別のルールでも Zend Code Analyzer が使えるってことになりそう。
posted at 17:47:28 on 2008-06-01 by miau - Category: PHP No Trackbacks - Permalink

TrackBack

このエントリにトラックバックはありません
現在トラックバックは受け付けていません。

Comments

No comments yet

Add Comments

現在コメントは受け付けていません。
お手数ですが、 こちら のコメント欄にでも記載していただければと思います。