miau's blog?

PHP_CodeSniffer のつづき

PHP_CodeSniffer の --standard オプション比較 - miau's blog?

ここで書き漏らした PHP_CodeSniffer の諸々について。




■Zend Code Analyzer のインストールについて

Zend Code Analyzer 入れてると、--standard=Zend で追加のチェックもやってくれる件。これ、マニュアルにも載ってたんだけど見落としてて↓の blog 見て存在に気づいた。

webプログラマーのメモ ≫ PEARのPHP_CodeSnifferのインストール及び使用法 | php, MySQL, PostgreSQL, apache, Linux等の技術メモです。

そして、Zend Code Analyzer へのパスを設定します。
$ sudo phpcs --config-set zend_ca_path /path/to/ZendCodeAnalyzer


(2010-01-14 追記)

以降で Zend Analyzer の取り出し方を書いていますが、こちらのコメント欄にて、問題ある旨の指摘をいただいたので、ひとまず転載しておきます。

上記にて弊社製品 Zend Studio 5.5 の内部モジュールを取り出して利用する方法を掲載されていらっしゃいますが、該当製品はオープンソースではございません。
著作権法ならびに、使用許諾への違反状態となっておりますので、謹んでご連絡を差し上げる次第です。

(2010-01-14 追記 ここまで)

ところで Zend Code Analyzer って何?と調べてみると Zend Studio に付属してるみたい。無料で手に入れる方法ないの?ということで調べてみると、

Greg Sherwood: PHP_CodeSniffer and the Zend Code Analyzer

The only way I have been able to get ZendCodeAnalyzer is to download
the trial of Zend Studio and grab the executable from inside the archive.
You don't need to install Zend Studio; just download the right copy for your OS.

ふむふむ。じゃ、トライアル版落としてみますかね。

Zend Studio - Downloads - Zend.com

から Zend Studio v5.5(Windows版)をダウンロード。(Zend のユーザ登録が必要なので注意。)

ZendStudio-5_5_1.zip を Explzh とかで開く
→InstallerData\Disk1\InstData\RESOURCE1.ZIP をさらに Explzh で開く
→$IA_PROJECT_DIR$\data\modules\code-analyzer\windows\ZendCodeAnalyzer.exe をコピーする
って感じでやれば、確かにインストールしなくても OK だった。

で、phpcs --config-set zend_ca_path 〜 みたいな形で ZendCodeAnalyzer.exe へのパスを設定することになってるんだけど、この情報がどこに格納されるか確認しないと不気味なので調べてみた。

PHP は D:\xampp\php\php.exe のやつを使ってるんだけど、D:\xampp\php\PEAR\PHP\CodeSniffer.php によると、

$configFile = dirname(__FILE__).'/CodeSniffer.conf';
if (is_file($configFile) === false) {
$configFile = '\xampp\php\pear\data/PHP_CodeSniffer/CodeSniffer.conf';
}

とのことなので、デフォルトでは D:\xampp\php\PEAR\data\PHP_CodeSniffer\CodeSniffer.conf が使われるけど、自分で D:\xampp\php\PEAR\PHP\CodeSniffer.conf を作っておいた場合はそっちを使ってくれるってことかな?(未確認)

まあある程度安心できたので、さっきのファイルを D:\xampp\php\ZendCodeAnalyzer.exe に配置して、

phpcs --config-set zend_ca_path D:\xampp\php\ZendCodeAnalyzer.exe

こんな感じで実行。D:\xampp\php\PEAR\data\PHP_CodeSniffer\CodeSniffer.conf を確認すると、ちゃんと設定されてました。

<?php
$phpCodeSnifferConfig = array (
'zend_ca_path' => 'D:\\xampp\\php\\ZendCodeAnalyzer.exe',
)
?>


■--standard=PEAR の「Equals sign not aligned with surrounding assignments; expected」について

前項で「長くなるから」って残しておいたやつ。このエラーどういうことかというと、

$url = $this->getUrl();
$this->here = $this->base . '/' . $url;

こういう代入文の連続は、

$url = $this->getUrl();
$this->here = $this->base . '/' . $url;

こんな感じで「=」の位置を揃えろってことみたい。なんだそれ。

このチェックを採用したくない理由は、ぱっと思いつくだけで 2 つ。
・diff したときに無駄に変更行が増えてわかりにくい。Trac みたいに行内の差分差分位置もある程度ハイライトしてくれるならまあいいんだけど。
・整形のための手段がない。(少なくとも Eclipse PDT ではそこまでのフォーマッティングは行えない。)そんな本質的でない整形で開発者の時間を割きたくない。

これって一般的な書き方だっけ?ということで Code Complete第2版〈下〉 を読んでみると、「代入分の右辺は揃えない」というそのまんまの項があって(p357)、このように書かれている。

 本書の初版では、リスト31-46のように、代入文の右辺で整列する方法を推奨
していた。
(リストは省略)
 この10年間で得た知識から、このインデントスタイルは見栄えは良いかもしれ
ないが、変数名が変更されたり、スペースとタブを置換するツールを使用したり
すると、等号(=)を整列した状態に保つのが面倒であることがわかった。また、
プログラムの行をインデントレベルが異なる場所へ移動したときも、このスタイ
ルを維持するのは難しい。
 他のインデントのガイドラインとの整合性や保守性を考慮すると、リスト
31-47に示すように、代入演算が含まれているステートメントは、他のステート
メントと同じように扱うべきだろう。

つまり、逆に避けるべき記法とされている。他の項(p346)でも「等号(=)を揃える」というのは「古くさい方法」と一蹴されてたり。

PEAR ってなんでこんな書き方推奨してんの?と思って原文を読んでみたら、実は may としか書かれてない。

PEAR :: Manual :: Function Calls

In the case of a block of related assignments, more space may be
inserted to promote readability:

ってことは PHP_CodeSniffer のチェックが厳しすぎるってことだよなぁ。文句つけたほうがいいのかな、と思ったら極端な例に絡めて同じようなことを言ってる人はいて。

PEAR :: Request #11561 :: equal sign alignment and long lines

中の人曰く、

Both the alignment and line length sniffs produce warnings only. PEAR
does not require you to meet either of these standards; they just
suggest sticking to these guidelines where you can.

I can add an option to check the line length before suggesting the
alignment, but I wont change the default settings of the PEAR standard
without the PEAR CS being modified.

「warning なんだから気にすんなよ。PEAR コーディング標準は守れる範囲で守れればいいんだし。」「PEAR のコーディング標準が変わらない限り、--standard=PEAR の動作を変える気はないよ。」ってことみたい。
PHP_CodeSniffer で言うところの warning は一般的にいうところのもっと低いレベルの警告(notice だとか information だとか)だと思ってたほうがいいみたいね。-n オプションで warning 抑止するのを標準にしようかな。それかやっぱり PEAR やめて Zend でいくか。

PEAR :: Request #11555 :: Equals sign alignment warnings too hard

So what you'll probably have to do is either ignore the warnings that
you don't want to fix, or create your own standard.

こっちも上記のようなコメント+「warming 無視するか自前のコーディング標準を作ってくれ。」と。

PEAR のほうの記述が変わったらこの辺の挙動も変えてくれるんだろうけど、PEAR のコーディング規約に文句つけるには ML に入って報告する形がいいんだそうな。Web ページで軽くバグ報告するのに比べて ML は疲れるんだよなぁ。英語がもっと気楽に書ければいいんだけど。

■スペースでのインデントについて

前項では --tab-width=4 にしてたのでさらっと流したけど、本当はインデントをタブで書いたときに文句言われるのも不満だったり。個人的にベストだと思ってるのはこのやり方。

最速インターフェース研究会 :: タブとスペースと萌ディタの話

「自分は行頭はタブで揃えて、それ以降の文字揃えが必要な場合はスペースを使う」と。これが一番柔軟なんだよね。私はサクラエディタがメインなので、以下のマクロを ALT+Q とかに割り当てて使ってます。

サクラエディタ/マクロ/タブサイズ変更 - 2->4->8 と変更

1 ストロークでタブ幅を切り替えられる環境ってのは重要で、この環境を整えてしまえばこの方法の便利さがわかるだろうし、「全部スペースで」なんて頭の固いことを考えなくなると思う。(逆に 2 タブや 8 タブで作られたファイルを受け付けるのが快感になったりとかして・・・。)この環境も整えずに批判してるんだとしたら、そんな意見受け付ける価値はないと思うんだけど。

・・・と一通り批判したあとでなんだけど、会社ではこの辺説明するの面倒だから全部スペースでもいいと思ってる。でもハッカーっぽい皆さんの間でもこれが標準として広まるのは楽しくないなぁ。

■コードの整形について

Perl でいうところの PerlTidy っぽいのないのかな?ってことで調べてみると、無いこともないみたい。

○PHP_Beautifer

throw new CybozuLabsException() - PHP_CodeSniffer vs PHP_Beautifer

で、変換したものを再度CodeSnifferにかけると、、
(中略)
なんとエラーが増えてしまいます!!!

んー・・・問題が行内の文字数制限と「=」の周囲のスペースだけなら WARNING だからいいんだけど、foreach 周囲の空白まで削られるのはいただけないな。それくらいなら余計なことやらないぶん Eclipse PDT のフォーマットのほうがいいや。

○phpCodeBeautifier

続ビューティー - p0t

っての使えば PEAR の書式も行けるそうな。でも一括で変換とかはできないらしいからイマイチ。

■CakePHP で使う上でのメモ

オプションで --extensions=inc,php,ctp にするの忘れないようにしないと。(.inc があったかは覚えてないけどとりあえずメモ。)

で、チェックの対象は自分で新規作成したファイルについてだけにしようかと。CakePHP についてくるファイルは対象外にしないと、Cake のバージョンアップのときにマージするの面倒だしね。新規作成のたびにフォーマット整えるくらいなら Eclipse PDT で対応できるだろうし、それほど苦痛じゃないでしょ。

■PHP_CodeSniffer と Eclipse の連携

PHP_CodeSniffer をちょっといじって(--report のオプションを追加して)、出力を php -l の結果(↓こういうの)にあわせてやれば Eclipse の「問題」タブに出せて便利なんじゃね?と思ってちょっと調べてみた。

PHP Parse error: syntax error, unexpected T_CLASS, expecting T_STRING in dispat
cher_damedame.php on line 42
Errors parsing dispatcher_damedame.php

今回は Eclipse PDT でいこうと思ってるので、ちょっとソース読んでみたんだけど・・・これ php -l の結果使わずに自前でパースやってるのか。道理で軽快に動作するわけだ。

でもこれじゃうまく連携できないな。こういう方法で自分でコマンド実行してやる+対象行に自分でジャンプしてやるしかないのかなぁ。

PHP_CodeSnifferをEclipseから実行する

これじゃ面倒だから、Eclipse でのチェックはオプションくらいに考えて、サーバ側でのチェックをメインにしようかな・・・。

ちなみに PHPEclipse の場合は、
・自分で --report のオプションを増やす
・「php -l && phpcs」みたいなことを行うバッチを作る
・「PHP External Parser Command」の欄を「php -l」から上記のバッチに変更する
って手順でうまくいくんじゃないかと思う。(余裕ないので未検証。)

■--report=checkstyle って何?

--report のオプションで checkstyle ってのがあるから、Eclipse の CheckStyle プラグインと連携できたりするのかなと思ったら、そんなことなかった。Ecipse の CheckStyle プラグインは Java でしか使えないし、外部コマンドの実行結果を取り込んだりはできない。

じゃあこれは何なのかというと、CruiseControl との連携したりする場合に使う。このオプションの意図についてはこの辺参照。

Greg Sherwood: CruiseControl and PHP_CodeSniffer

このやり方も検証済なんだけど、長くなるのでさらに別項で。


(2008-06-17 追記)

今回は CakePHP を使ってるんで、インデントはタブを採用することにした。

Development/CodingStandards - CakePHP : The Rapid Development Framework for PHP - Trac

に「One tab will be used for indentation.」って思い切り書いてるし。core はタブのままにして自前コードだけスペースでインデント、というのも考えたけど、マージが面倒になるだけだからやめておいた。

で、実際その運用をやってみてちょっと気になったのは、Trac やらメール(SVN の post-commit hook でメール飛ぶようになってる)ではやっぱり 8 タブで表示されてるってこと。間延びして見づらいね、これじゃ。
Trac は設定でタブ幅変えられるけど、メーラは人それぞれだから 8 タブのまま見てる人もいるんだろうなぁ。まあいいけど。
posted at 19:35:57 on 2008-06-01 by miau - Category: PHP No Trackbacks - Permalink

TrackBack

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

Comments

No comments yet

Add Comments

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