WordPress
phpcs
コーディング規約
WordPressDay 12

WordPressの案件には是非コーディング規約を導入してください!

More than 1 year has passed since last update.

この記事はWordPress Advent Calendar 2017 12日目へのエントリーです。

コーディング規約について

はじめに

コーディング規約使ってますか?
コーディング規約はPHPやHTMLを書くときのルールです。
日本語には句読点やカギカッコ、字下げなどに一定のルールがあります。英語でもカンマ、ピリオドの打ち方、スペーシングの使い方にルールがあります。
プログラムやHTMLコードでもそれぞれのルールがあり、そのルールをまとめたものがコーディング規約と呼ばれています。
その規約を守ることで可読性の高いコードを書くことができます。特に複数人でコードを見る機会がある場合にはとても便利になります。
またコーディング規約には明確な「答え」があるので、迷うことが少ないです。
答えに沿ってコーディングをすればよいので、コーディングのレベルアップにつながるなー、と思っています。

以前使い方を記事にしましたが、改めて実務で使ってみましたので、その手順についてまとめてみました。

なぜコーディング規約を導入するか

コーディング規約は「コードを読みやすくすること」です。
コードを読みやすくするメリットは下記のとおりです。

  • 他人、特にチームメンバーで読みやすい
  • バグを防ぎやすい
  • 未来の自分にも優しい

他人の書いたコードは本当に読みにくいですよね。

WordPressのコーディング規約

ひとえにコーディング規約と言っても、言語ごと、環境ごとに色々な規約があります。
WordPressではそれ独自のコーディング規約が定義されています。

https://wpdocs.osdn.jp/WordPress_コーディング基準

規約 URL
CSS コーディング規約 https://wpdocs.osdn.jp/CSS_コーディング規約
HTML コーディング規約 https://wpdocs.osdn.jp/HTML_コーディング規約
JavaScript コーディング規約 https://wpdocs.osdn.jp/JavaScript_コーディング規約
PHP コーディング規約 https://wpdocs.osdn.jp/PHP_コーディング規約

ざっくり全体的な特徴を述べると、

  • スペースは多めに開ける(丸括弧、波括弧の前後など)
  • 改行も多めに入れる(CSSセレクタ、メソッド類)

です。
ちなみにそれぞれの定義はそれほど長くないので、是非とも一読されることをおすすめします。

Screen Shot 2017-12-12 at 22.31.27.png

導入方法

WordPressのファイル構成

今回想定しているのは「WordPressによるテーマ作成プロジェクト」です。
実際に仕事でWordPressプロジェクトの場合、多くはテーマ作成かなと思います。

今回例として作成するテーマは _s を使って作りました。

https://underscores.me

Screen Shot 2017-12-12 at 9.00.15.png

ファイル構成はこんな感じです。

Screen Shot 2017-12-12 at 9.00.39.png

今回のリポジトリはこちらに置いてみました。

https://github.com/yousan/wpcs-1

ComposerでのPHPCS、WPCS、PHP Compatibilityのインストール

では実際にWordPressのテーマにPHPCSを適用してみます。

まずはComposerでPHPCS (PHP Code Sniffer) をインストールします。
Composerではマシン環境全体にインストールする「グローバルインストール」と、プロジェクトごと(リポジトリごと)にインストールする「ローカルインストール」があります。
(「グローバル」という名称は見かけますが、「ローカル」の名称が違っていたらごめんなさい 参考: https://getcomposer.org/doc/00-intro.md#locally

$ composer require --dev squizlabs/php_codesniffer

続いてWordPressのコーディング規約のセットをインストールします。
https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards

このコーディング規約のルールセットは WPCS (WordPress Coding Standards)という略称が使われています。

$ composer require --dev wp-coding-standards/wpcs

続いてPHPのバージョンごとの言語互換性をチェックするルールセット、PHP Compatibilityをインストールします。
https://github.com/wimg/PHPCompatibility

$ composer require --dev wimg/php-compatibility

ここまでできたらphpcs -iで導入されたルールセットについて確認しておきます。

Screen Shot 2017-12-12 at 9.18.57.png

PHPCSにWPCS、PHP Compatibilityのルールセットを追加

続いて、最初にインストールしたPHPCSに、WPCS、PHP Compatibilityのルールセットを設定します。

$ ./vendor/bin/phpcs --config-set installed_paths `pwd -P`/vendor/wp-coding-standards/wpcs,`pwd -P`/vendor/wimg/php-compatibility

僕は何度もPHPCSを使ってきましたが、このルールセットの追加で躓くことが多かったので注意が必要です。

注意すべき点を下記に列挙します。

  1. 呼び出すPHPCSの実行ファイルの場所に注意すること。(PHPCSをグローバルインストールした場合とローカルインストールした場合で違う。今回はローカル。)
  2. 追加するルールセットは絶対パス(若しくはPHPCSをからの相対パス)で記述すること。問題回避のために絶対パスの方が良さそう。
  3. --config-set で設定した値はconfファイルで確認できる。
  4. 複数のルールセットを定義する場合にはカンマ区切り。

今回はComposerでローカルインストールを行ったので、./vendor/bin/phpcsを呼び出してコンフィグをセットします。
ここでグローバルなphpcsを呼んでしまうと別の設定になってしまうので注意が必要です。

追加されるルールセットは絶対パスが良いです。
特にリポジトリルートの絶対パスを調べるpwd -Pを基に設定すると間違いが起こりにくいです。
(例 pwd -P/vendor/wimg/php-compatibility )

--config-setCodeSniffer.confのファイルに書き出します。
うまく動かない場合にはこちらを確認すると良いです。

$ cat ./vendor/squizlabs/php_codesniffer/CodeSniffer.conf
<?php
 $phpCodeSnifferConfig = array (
  'installed_paths' => '/Users/yousan/git/wpcs-1/vendor/wp-coding-standards/wpcs,/Users/yousan/git/wpcs-1/vendor/wimg/php-compatibility',
)
?>

実際に動かしてみる

_sのテーマファイルの場合、phpcs.xmlがサンプルでついてきています。
そちらを基に動かしてみます。

下記のコマンドで動かすことができます。

$ ./vendor/bin/phpcs --standard=./themes/wpcs/phpcs.xml

Screen Shot 2017-12-12 at 9.19.16.png

動きましたね!

エラーがたくさん出てきました。
これらのエラーを直していくことになります。

またエラーメッセージの下の方に「自動整形できるよ!」ということが書かれています。
実は簡単なコーディング規約違反については、PHPCSに同梱のPHPCBF (PHP Beautifier and Fixer) で修正できます。
ということで自動整形を行ってみます。

$ ./vendor/bin/phpcbf --standard=./themes/wpcs/phpcs.xml

Screen Shot 2017-12-12 at 9.21.47.png

すごいですね!

Gitで実際にどういった箇所が直されたのか確認できます。

Screen Shot 2017-12-12 at 22.36.54.png

https://github.com/yousan/wpcs-1/commit/47b521c38126bf5bf9d061b7ce8d946e632196f0

どの規約を適用するか

ここまで適用してきたPHPCSでは、themes/wpcs/にあるphpcs.xmlというファイルを使っていました。
phpcsコマンドでは--standardで与える設定XMLファイルを基に、どういった規約を適用するか、ということを決めることが出来ます。

WordPressではコーディング規約を定めていますが、プロジェクトによっては外したい規約もあるかと思います。
実際に僕が外している規約について紹介します。

ルール名 概要
WordPress.Files.FileName.InvalidClassFileName 固定ページ内にクラスを入れることを許容。他から参照されない固定ページで完結するビューのコントロールロジック(ビジネスロジックはNG!)の場合、固定ページ内に書いたほうがキレイになるので許容しています。
WordPress.Files.FileName.NotHyphenatedLowercase 固定ページのスラッグにアンダースコアを許容。
WordPress.XSS.EscapeOutput.OutputNotEscaped HTMLのエスケープ漏れを許容。こちらはできれば無効化しないでスタートするほうが良いです。
WordPress.VIP.AdminBarRemoval.RemovalDetected 管理バー非表示を許容。
Squiz.Commenting.InlineComment.InvalidEndChar コメント文の末尾にピリオド類が無いことを許容。日本語句点や一文のみ体言止めの場合にはいらないので外しています。
Generic.Commenting.DocComment.ShortNotCapital コメント文を大文字で始めないことを許容。こちらもできれば外さないほうが良い。コメントに iframe といった HTMLタグなどの用語に対応のため外しました。

下記は実際にプロジェクトでつかった設定ファイルです。

    <!-- Include the WordPress ruleset, with exclusions. -->
    <rule ref="WordPress">
        <!-- _sのルールセットを参照 @link https://github.com/Automattic/_s/blob/master/codesniffer.ruleset.xml -->
        <exclude name="Generic.WhiteSpace.ScopeIndent.IncorrectExact" />
        <exclude name="Generic.WhiteSpace.ScopeIndent.Incorrect" />
        <!-- 長めの関数の呼び出し時に複数行にしなければならない制約を無視 -->
        <exclude name="PEAR.Functions.FunctionCallSignature.Indent" />

        <!--<exclude name="Generic.WhiteSpace.ScopeIndent.IncorrectExact" />-->
        <!--<exclude name="Generic.WhiteSpace.ScopeIndent.Incorrect" />-->
        <!--<exclude name="Squiz.Commenting.ClassComment" />-->
        <!--<exclude name="Squiz.Commenting.FunctionComment" />-->
        <!--<exclude name="Generic.Commenting.DocComment" />-->
        <exclude name="WordPress.VIP" />

        <!-- 固定ページ内にクラスを入れることを許容 -->
        <exclude name="WordPress.Files.FileName.InvalidClassFileName" />
        <!-- ファイル名の決定時にslugをサポートするため、page-hoge_fuga.php を許容する -->
        <exclude name="WordPress.Files.FileName.NotHyphenatedLowercase" />
        <!-- HTML系のエスケープ強制を無視 -->
        <exclude name="WordPress.XSS.EscapeOutput.OutputNotEscaped" />

        <!-- 管理バーの非表示を許容 -->
        <exclude name="WordPress.VIP.AdminBarRemoval.RemovalDetected" />

        <!-- コメント分の末尾をフルストップ、ビックリマークやはてなで終わらせる必要があるルールを除外する -->
        <exclude name="Squiz.Commenting.InlineComment.InvalidEndChar" />
        <exclude name="Squiz.Commenting.FunctionComment.ParamCommentFullStop" />

        <!-- コメント文は大文字で始める制約を除外 ex.) iframeについて -->
        <exclude name="Generic.Commenting.DocComment.ShortNotCapital" />

        <!-- _sのテーマに元々ある多言語化周りの警告を無視する -->
        <exclude name="WordPress.WP.I18n.MissingTranslatorsComment" />

        <!-- PHPの開始タグ、閉じタグ <?phpと?> を独立した行に置かなければならない条件を除外 -->
        <exclude name="Squiz.PHP.EmbeddedPhp.ContentAfterOpen" />
        <exclude name="Squiz.PHP.EmbeddedPhp.ContentAfterEnd" />
        <exclude name="Squiz.PHP.EmbeddedPhp.ContentBeforeOpen" />
        <exclude name="Squiz.PHP.EmbeddedPhp.ContentBeforeEnd" />

        <!-- 引数の説明を省略可能にする -->
        <exclude name="Squiz.Commenting.FunctionComment.MissingParamTag" />
    </rule>

導入してみて

導入してみての感想

ここ数年、僕が抱えるプロジェクトが徐々に大きくなり、僕がリーダーとして複数人で開発するケースが増えてきていました。
WordPressに限りませんが、コミットされるコード、バグのトラブルシュートのヘルプ、欠員時など、プロジェクトの責任者は全てのコードを見る必要があります。
ですがコードにはエンジニアのクセがあり、こだわりがあり、どうしても読みづらく感じていました。そこでその解消のためWordPressのプロジェクトにPHPCSを導入しました。
WordPressのコーディング規約のWiki自体は「コレに合わせましょう」ということで周知していましたが、人の目ですとどうしても守ってもらえないことが多かったです。
PHPCSを使うことでチームメンバーにほぼ強制化できたため、とても便利でした。
PHPCSありがとう!

特にPHPCSはCIに組み込むことができます。チームメンバーにプルリクエストを投げて貰う前にPHPCSをテストとして通すことで、コーディング規約違反を排除することができました。
すごくありがたかったです。

というわけでみなさんも良い自動化ライフを!