社内でかなり前に CakePHP2 で開発されていたアプリを見たら、リファクタリングうんぬんの前にコーディング規約が乱れすぎていて、読むのもつらい状況でした。
手動で直せる分量ではなく、どうしたものかと困っていましたが、2014年12月にリリースされていた PHP_CodeSniffer 2.0.0 からコーディング規約チェッカー (phpcs) の他に修正もできるツール (PHPCBF; PHP Code Beatifier and Fixer) も同梱されるようになっていたので、これを使ってみることにしました。
インストール手順
今回は Composer を使って、プロジェクトグローバルに PHPCS をインストールしてみます。
Composer をインストール
curl http://getcomposer.org/installer | php
CodeSniffer をインストール
composer global require "squizlabs/php_codesniffer"
composer global show --installed
PATH に Composer がインストールするバイナリの保存先ディレクトリを設定する
vim ~/.bash_profile
(PATHの行を以下のように修正)
PATH=$PATH:$HOME/bin:$HOME/.composer/vendor/bin
source ~/.bash_profile
phpcs -h
phpcbf -h
(それぞれのツールのヘルプが表示されれば OK)
CakePHP 用ルールセットをインストール
cakephp/cakephp-codesniffer の master ブランチにある最新バージョン (2.0.x) は CakePHP3 に合わせて 1PSR-2 準拠になっており、CakePHP2のコーディング規約とかなり違うので、2update-fxer-2 ブランチ を使います。
mkdir sniffs
curl -LO https://github.com/cakephp/cakephp-codesniffer/archive/update-fxer-2.zip
unzip update-fxer-2.zip -d sniffs
cd sniffs/
mv cakephp-codesniffer-update-fxer-2 CakePHP
cakephp-codesniffer のルールセットを phpcs に登録する
phpcs --config-set installed_paths ~/sniffs/
phpcs -i
phpcbf -i
(CakePHP が追加されていれば OK)
添削&修正してみる
phpcs, phpcbf ともに、--standard=CakePHP
というオプションを付ければ CakePHP2 のルールに沿ってコードの添削&修正が行われます。
添削
規約違反を一覧で表示するには以下のように叩きます。
$ phpcs --standard=CakePHP /PATH/TO/MYAPP/app/Controller/AppController.php
FILE: /PATH/TO/MYAPP/app/Controller/AppController.php
----------------------------------------------------------------------
FOUND 93 ERRORS AFFECTING 58 LINES
----------------------------------------------------------------------
35 | ERROR | [x] Tabs must be used to indent lines; spaces are not
| | allowed
35 | ERROR | [ ] Scope modifier not specified for member variable
| | "$today"
...
----------------------------------------------------------------------
PHPCBF CAN FIX THE 66 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------
Time: 41ms; Memory: 4.5Mb
具体的な修正内容を確認したければ、--report=diff
を付けます。
$ phpcs --report=diff --standard=CakePHP /PATH/TO/MYAPP/app/Controller/AppController.php
--- /PATH/TO/MYAPP/app/Controller/AppController.php
+++ PHP_CodeSniffer
@@ -32,80 +32,82 @@
*/
class AppController extends Controller {
- var $today = "";
- var $components = array('RequestHandler', 'Security');
- var $oneTimeString = "";
...
+ var $today = "";
+
+ var $components = array('RequestHandler', 'Security');
+
+ var $oneTimeString = "";
修正
phpcs の代わりに phpcbf コマンドを使えば、ファイルが修正されます。
$ phpcbf --standard=CakePHP /PATH/TO/MYAPP/app/Controller/AppController.php
Changing into directory /PATH/TO/MYAPP/app/Controller
Processing AppController.php [PHP => 732 tokens in 111 lines]... DONE in 17ms (66 fixable violations)
=> Fixing file: 0/66 violations remaining [made 3 passes]... DONE in 60ms
Patched 1 file
Time: 123ms; Memory: 5.5Mb
コーディング規約違反は心の乱れ。素早く直しましょう。
補足: Inflector に依存する修正がエラーで止まる
CakePHP には「大文字<->小文字」や「CamelCase <-> snake_case」の変換を司る Inflector というクラスが存在しますが、これに依存するコード修正が動くとエラーになってしまいました。
$ phpcbf --standard=CakePHP /PATH/TO/MYAPP/app/Controller/FooBarController.php
Changing into directory /PATH/TO/MYAPP/app/Controller
Processing FooBarController.php [PHP => 2400 tokens in 327 lines]... DONE in 75ms (492 fixable violations)
=> Fixing file: 492/492 violations remainingPHP Fatal error: Class 'Inflector' not found in /home/vagrant/sniffs/CakePHP/Sniffs/NamingConventions/ValidVariableNameSniff.php on line 281
[PHP => 2400 tokens in 327 lines]...
どうやら phpcbf が Inflector を読み込めていないようです。
phpcbf 実行時にどう読み込むべきか悩みましたが、ひとまず今はコード修正だけできればいいので、phpcbf スクリプトの中で直接 Inflector を require_once
するという超汚いパッチで回避しました。
~/.composer/vendor/squizlabs/php_codesniffer/scripts/phpcbf
を以下のように修正します。
# !/usr/bin/env php
<?php
// 以下の行を追加
require_once '/PATH/TO/MYAPP/Vendor/cakephp/cakephp/lib/Cake/Utility/Inflector.php';
もっとスマートなやり方があれば教えて下さい。
参考
- PHP_CodeSniffer - CodeSnifferのインデントをタブ対応にする方法 - Qiita
- PHP Code Snifferを使ってCakePHPのコーディング規約をチェックする - Composerで簡単インストール
- Fixing Errors Automatically · squizlabs/PHP_CodeSniffer Wiki
- FriendsOfPHP/PHP-CS-Fixer
- squizlabs/PHP_CodeSniffer