PHP_CodeSnifferを使うと、PHPの記述がコーディング規約に沿ったものであるかを機械的に確認してくれるので、開発者の不注意による規約違反を防ぐことができ、またレビュー時の負担軽減にも繋がります。
今回はPHP_CodeSnifferを導入して、git commit時にチェックが走るような設定を行います。
なお使用した環境は以下の通りです。
- PHP 7.4
- Git 2.20
PHP_CodeSniffer
インストール
composerを使ってPHP_CodeSnifferをインストールします。プロジェクトのルートディレクトリで以下を実行します(2021年1月現在は3系が安定版のようです)。
$ composer require --dev squizlabs/php_codesniffer:3.*
インストールできたら、vendor/bin
にphpcs
とphpcbf
という実行ファイルが存在するはずです。
$ ls vendor/bin/
phpcbf phpcs
動作確認
実際に規約違反のPHPファイル、Hoge.php
、Fuga.php
、Piyo.php
を用意して動作検証してみます。
/
├ src/
| └ Models/
| ├ Fuga.php
| ├ Hoge.php
| └ Piyo.php
└ vendor/
<?php
namespace Src\Models;
class Hoge
{
public function to_string()
{
return 'hoge';
}
}
キャメルケースでないメソッド名が存在しますので、PSR-1: Basic Coding Standardに違反しています。Fuga.php
、Piyo.php
もクラス名が違うだけでHoge.php
と同様に違反している状態とします。この状態でphpcs
を使ってチェックしてみます。
$ ./vendor/bin/phpcs --standard=PSR12 ./src
FILE: /var/www/html/src/Models/Piyo.php
-----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-----------------------------------------------------------------------
7 | ERROR | Method name "Piyo::to_string" is not in camel caps format
-----------------------------------------------------------------------
FILE: /var/www/html/src/Models/Fuga.php
-----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-----------------------------------------------------------------------
7 | ERROR | Method name "Fuga::to_string" is not in camel caps format
-----------------------------------------------------------------------
FILE: /var/www/html/src/Models/Hoge.php
-----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-----------------------------------------------------------------------
7 | ERROR | Method name "Hoge::to_string" is not in camel caps format
-----------------------------------------------------------------------
Time: 21ms; Memory: 4MB
このように規約違反が検出されました。なお今回はPSR-12: Extended Coding Styleに基づいて検証しています(PSR12
)が、使用する規約は--standard
オプションによって変更できます(インストールされている規約は-i
で確認可能)。
$ ./vendor/bin/phpcs -i
The installed coding standards are PSR2, MySource, Squiz, PSR12, PEAR, Zend and PSR1
フィルタオプション
今回はgitと連携して使用しますので、--filter
オプションで指定できるGitStaged
,GitModified
の各フィルターに関して確認しておきます。それぞれ以下のようなフィルターになります。
GitModified
… 修正、またはリポジトリに追加したファイルのみを対象とするGitStaged
… ステージング状態のファイルのみを対象とする
実際の挙動を見てみます。各ファイルの内容はそのままでソース管理の状態を以下とします。
Hoge.php
… リポジトリに追加した状態Fuga.php
… リポジトリに追加してステージング状態Piyo.php
… コミット済み
$ git status -s
A src/Models/Fuga.php
?? src/Models/Hoge.php
この状態でフィルターを変更して実行してみると、チェック対象が絞りこまれているのがわかります。
./vendor/bin/phpcs --standard=PSR12 ./src
FILE: /var/www/html/src/Models/Piyo.php
-----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-----------------------------------------------------------------------
7 | ERROR | Method name "Piyo::to_string" is not in camel caps format
-----------------------------------------------------------------------
FILE: /var/www/html/src/Models/Fuga.php
-----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-----------------------------------------------------------------------
7 | ERROR | Method name "Fuga::to_string" is not in camel caps format
-----------------------------------------------------------------------
FILE: /var/www/html/src/Models/Hoge.php
-----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-----------------------------------------------------------------------
7 | ERROR | Method name "Hoge::to_string" is not in camel caps format
-----------------------------------------------------------------------
Time: 31ms; Memory: 6MB
./vendor/bin/phpcs --standard=PSR12 --filter=GitModified ./src
FILE: /var/www/html/src/Models/Hoge.php
-----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-----------------------------------------------------------------------
7 | ERROR | Method name "Hoge::to_string" is not in camel caps format
-----------------------------------------------------------------------
Time: 64ms; Memory: 6MB
./vendor/bin/phpcs --standard=PSR12 --filter=GitStaged ./src
FILE: /var/www/html/src/Models/Fuga.php
-----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-----------------------------------------------------------------------
7 | ERROR | Method name "Fuga::to_string" is not in camel caps format
-----------------------------------------------------------------------
Time: 39ms; Memory: 6MB
Gitの設定
Gitフック
次にGitフックを使ってgit commit時にphpcs
が実行されるようにします。
.git/hooks
に以下の内容のpre-commit
という名前のシェルスクリプトを作成します。
#!/bin/sh
./vendor/bin/phpcs --standard=PSR12 --filter=GitStaged .
これで設定完了です。
動作確認
先の動作確認時と同様に規約違反のsrc/Models/Fuga.php
がステージング状態とします。コミットを試みるとコミット前にチェックが走り、エラーとなるため、コミットできなくなっていることが確認できます。
$ git status -s
A src/Models/Fuga.php
?? src/Models/Hoge.php
$ git commit -m "add Fuga Model"
FILE: /var/www/html/src/Models/Fuga.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
7 | ERROR | Method name "Fuga::to_string" is not in camel caps
| | format
----------------------------------------------------------------------
Time: 34ms; Memory: 6MB
$ git status -s
A src/Models/Fuga.php
?? src/Models/Hoge.php
コミットするためには、規約違反を解消しなければなりません。そのため、このpre-commit
を開発者全員で共有していれば、規約違反のコードがリポジトリに含まれることは(ほぼ)無くなります。
まとめ
PHP_CodeSnifferを導入して、git commit時にコーディング規約チェックが走るようにしてみました。大抵の場合は今回の設定で事足りるのですが、"(ほぼ)無くなります"と書いているように、実はこの設定だとチェックをすり抜けてしまうことが可能なので、次回もう少し深堀りしてみようと思います。