【VSCode×phpcs】WordPressコーディング規約の除外ルールを作る

プログラミングにおいてコードの可読性を保つ為にどの言語でも使われている**コーディング規約**。
WordPressにおいてもWordPressコーディング規約が存在し、このコーディング規約を守る事で同じWordPress開発者同士のコードレビューのしやすさや保守においても効果を発揮します。
（余談ですがコーディング規約に則った綺麗なコードを書く事は"他人から見やすい"はもちろんですが、**そのコードを見慣れる事によって"自分が他人のコードを見やすくなる"**事に繋がり、こっちの得が大きいと思っています。）

しかしPHPやJavaScript、Pythonといった言語そのものではなくWordPressやLaravel、VueやReact、DjangoのようなCMSやフレームワークの場合どうしてもレガシーな記述を求められる事があります。
これはそもそもCMSやフレームワークは言語を後追いするものだったり、後方互換性のためだったり理由は様々ですが個人的にはストレスになることも。

**2023/9/2追記**
wp-coding-standards/wpcsパッケージ3系がリリースされ、一部のルール名が変更になっています。
当記事は新しいルール名に修正していますが、2系を使っている方は適宜以下のように読み替えてください。

| 旧 | 新 |
|:-:|:-:|
|`Generic.Arrays.DisallowShortArraySyntax`|`Universal.Arrays.DisallowShortArraySyntax`|
|v2系まではこちらを使用|v3系以降はこちらを使用|

なお、新しいルール名は以下のwpcs3.0.0アップグレードガイドに一覧があるので合わせて確認してください。

[Upgrade Guide to WordPressCS 3.0.0 for ruleset maintainers](https://github.com/WordPress/WordPress-Coding-Standards/wiki/Upgrade-Guide-to-WordPressCS-3.0.0-for-ruleset-maintainers)

**2021/6/14追記**
composer.jsonにコマンドを追加して、以下のようにコマンドを叩けばすぐに設定できるようにしました。
~~いちいち./vendor/bin/phpcs --config-set installed_pathsとか書くのがめんどくさい~~

このcomposer.jsonとphpcs.xmlを入れてGitHubにテンプレートリポジトリを作っておけば、テンプレートリポジトリを元に新規リポジトリを作成して`git clone`して`composer up`コマンドでインストール、`composer wplint-set`と3つコマンドを打つだけですぐに開発が進められます！

（後述するphpcs.xmlもリポジトリに含めておけば、PHPCSはどの規約を適用するか設定しなくてもデフォルトでphpcs.xmlに指定した`rule ref`の値のルールを優先します。そのため`./vendor/bin/phpcs --config-set default_standard WordPress`とコマンドを打つ必要も無くなります。）

```json:composer.json
{
    "require-dev": {
        "squizlabs/php_codesniffer": "*",
        "wp-coding-standards/wpcs": "*"
    },
    "scripts": {
        "wplint": "./vendor/bin/phpcbf",
        "wplint-set": "./vendor/bin/phpcs --config-set installed_paths 'vendor/wp-coding-standards/wpcs'",
        "wplint-rules": "./vendor/bin/phpcs -i"
    }
}
```

これで以下のようにコマンドを打てばOKです。

```bash:command
// ルールチェック&自動整形
$ composer wplint xxx.php

// PHP_CodeSnifferのルールにWordPressのルールセットを追加
$ composer wplint-set

// PHP_CodeSnifferのルール一覧を確認
$ composer wplint-rules
```

多分ほとんどの方はVSCode等のエディタ上でチェック＆自動整形を行うと思いますが、一応コマンドで行う方のために設定してあります。
自動整形はいらないよ！という方はwplintの行を以下のように書き換えてください。

```diff_json:composer.json
"scripts": {
-       "wplint": "./vendor/bin/phpcbf",
+       "wplint": "./vendor/bin/phpcs",
        "wplint-set": "./vendor/bin/phpcs --config-set installed_paths 'vendor/wp-coding-standards/wpcs'",
        "wplint-rules": "./vendor/bin/phpcs -i"
    }
```

### WordPressはarray()の短縮構文が非推奨
今回WordPressプラグインを作るにあたり初めてWordPressコーディング規約を導入しました。
そこで現れるエラーの数。

```php:php
    $array = []; //エラー
    $array = array(); //推奨
```

このように標準のWordPressコーディング規約では**配列の短縮構文が非推奨**になっています。

「なるほど、PHP5.4以前の短縮構文が使えない環境にも配慮してるんだな・・・もうサポート切れてるんだし少なくとも短縮構文非推奨はやめていいんじゃない？一応公式見てみるか・・・」

[PHP コーディング規約 – Japanese Team — WordPress.org](https://ja.wordpress.org/team/handbook/coding-standards/wordpress-coding-standards/php/#declaring-arrays)

> 配列の宣言では、一般に長い配列構文 (array( 1, 2, 3 )) の方が短い配列構文 ([ 1, 2, 3 ]) よりも可読性に優れます。これは主に視覚的な面からから来ますが、加えて初心者にとっても分かりやすくなります。
>
> 配列は常に長い配列構文で宣言してください。

**・・・は？**

どうやらレガシーな環境への配慮ではなく可読性の話らしいです。
（もちろん可読性も非常に重要な点です、そこを否定するつもりはありません。）

コーディング規約を遵守することは非常に重要です。
とは言え短縮構文なんてリリースされてもう何年も経っていますし、PythonでもJavaScriptでもSwiftでも配列は`$array = []`でそっちの方が慣れているのでモダンな記述もしたい。
そこでPHPのLinterである**PHP_CodeSnifferを使ってWordPressのコーディング規約を元にオリジナルのコーディング規約を作成**していきましょう。

## この記事でできること

- VSCode上でPHP_CodeSniffer（phpcs）を使用してWordPressのコーディング規約を自動Lintできるようにする
- 除外ルールを作成し、除外したルールについては怒られないようにする

## 環境

- composer（PHP_CodeSniffer/WordPressコーディング規約等に必要）
- VSCode

なおcomposerはインストール済みの前提です。
OSはMacを前提にしますが、WindowsやLinuxの方は適宜読み替えて下さい。

PHP_CodeSniffer等のインストールはローカルインストールで行います。
PHP_CodeSnifferはglobalでインストールが紹介される事が多い印象ですが、プロジェクトによって除外したいルールが違うという事もあると思います。
普段はWordPressコーディング規約に準拠するが、このプロジェクトだけは特定のエラーを除外したいとか。
もちろんどちらでもいいですが、僕個人的にはローカル環境を汚染しないローカルインストール（`--dev`）の方が好きです。

グローバルインストールする場合はpathを読み替えてください。

## 基本環境構築
それではPHP_CodeSnifferを動かせる環境を用意しましょう。

### composerでインストール
まずはcomposerを使ってPHP_CodeSnifferとWordPressコーディング規約をインストールします。
プロジェクトのルートディレクトリで以下のコマンドを実行して下さい。

```bash:command
//PHP_CodeSnifferインストール
$ composer require --dev squizlabs/php_codesniffer

//WordPressコーディング規約をインストール
$ composer require --dev wp-coding-standards/wpcs
```

インストールした各種ファイル類はプロジェクトルートディレクトリ内の`vendor`ディレクトリに格納されています。

```:vendorディレクトリ構成
project（ルートディレクトリ）
 ├-vendor
 |   ├-bin
 |   |  └-phpcs（コマンド）
 |   ├-squizlabs
 |   |  └-phpcodesniffer（PHP_CodeSniffer）
 |   └-wp-coding-standards（WordPressコーディング規約）
 |      ├-WordPress
 |      ├-WordPress-Core
 |      ├-WordPress-Docs
 |      └-WordPress-Extra
 ├-index.php（後で作成）
 └-phpcs.xml（後で作成）
```

PHP_CodeSnifferは`phpcs`コマンドを使用します（と言ってもVSCode側でリアルタイムプレビューするので初期設定以外ではほとんど使いません）。

```bash:command
//ヘルプ
$ ./vendor/bin/phpcs -h

//現在利用できるコーディング規約の確認
$ ./vendor/bin/phpcs -i
The installed coding standards are PEAR, Zend, PSR2, MySource, Squiz, PSR1 and PSR12
```

### PHP_CodeSnifferにWordPressコーディング規約を反映

```bash:command
$ ./vendor/bin/phpcs --config-set installed_paths 'vendor/wp-coding-standards/wpcs'

//コーディング規約確認
//WordPressの文字がいくつか追加されてればOK！
$ ./vendor/bin/phpcs -i
The installed coding standards are PEAR, Zend, PSR2, MySource, Squiz, PSR1, PSR12, WordPress, WordPress-Extra, WordPress-Docs and WordPress-Core
```

### VSCodeにphpcsプラグインをインストール
VSCode上でPHP_CodeSnifferをリアルタイムプレビューするにはphpcsという拡張機能（プラグイン）が必要です。
phpcsで一番上に出てくるのでインストールしておきましょう。

## テスト稼働
それではまずWordPress標準のコーディング規約でテストしてみましょう。

### コーディング規約にWordPressを指定

```command:command
$ ./vendor/bin/phpcs --config-set default_standard WordPress
```

### PHPファイルを作成
次に簡単なWordPressコーディング規約に反したPHPファイルを用意します。

```php:php
<?php
    //インデントは全てスペース4つ
    $array = [];

    if(!isset($array)) {
        echo '空だよ！';
    }
```

このPHPファイルはWordPressのコーディング規約を盛大に破っています笑。
インデントはスペースが許可されておらずタブで行うべきですがスペース4つ、配列の短縮構文やif内にスペースがなく他にもファイルコメントやら最後に1行空の行がないやらなんやら・・・

![スクリーンショット 2020-10-31 15.54.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601080/bce67268-8cc7-8090-d3a8-9912799e3609.png)


恐らく作っている最中にこんな感じで続々と赤波線が引かれ、コンソールの問題タブで次々と怒られると思います・・・笑。

![スクリーンショット 2020-10-31 15.55.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601080/43c6f7a8-e112-1a9a-9ec9-9f1dcef62494.png)

今回はたった7行のコードなのになんと21個も怒られてしまいました。
ではこれをオリジナルのルールとして、エラーのうち`Short array syntax is not allowed`を除外するように設定しましょう。

## オリジナルルールの作成
オリジナルルールはxml形式で記述する必要があります。
ルートディレクトリ直下に`phpcs.xml`を作成しましょう。

```xml:phpcs.xml
<?xml version="1.0"?>
<ruleset name="Custom WordPress">
    <rule ref="WordPress">
        <exclude name="Universal.Arrays.DisallowShortArraySyntax" />
    </rule>
</ruleset>
```

2行目の`ruleset name=`は好きに指定してOKですが、わかりやすいものにしておきましょう。
3行目の`rule ref=`で元となるルールを指定、今回はWordPressです。
4行目でexclude（除外）として配列の短縮構文を除外しました。
xmlはネストしないタグ（今回はexclude）の場合末尾の`/`が必須なので忘れないようにしましょう。

もちろん他のルールも除外することができます。
例えばインデントにスペースを許可したい場合は以下の通りです。

```xml:phpcs.xml
<exclude name="Generic.WhiteSpace.DisallowSpaceIndent" />
```

パッと除外したいルールをみたい場合[PHP_CodeSnifferのルールまとめ](https://qiita.com/blue32a/items/db049e091d4e7a469e6d)が非常に便利でした、この場を借りてお礼申し上げます！

作成が終わったら先ほどのPHPファイルを一度上書き保存してください。
`Short array syntax is not allowed`が消えましたね！

## 終わりに
ここまで散々配列の短縮構文が許可されていない事を仇のように除外してきましたが、基本は全てのルールに準拠する方が健全だと思っています。
ただし便利でモダンな記述ができないというのはストレスです。
WordPressのテーマやプラグイン製作時だけレガシーな記述をするのもちょっと嫌ですし・・・笑。

基本はやはりコーディング規約に準拠し、どうしても開発にあたって障壁（ストレス）になる部分だけをクリアにするというホワイトリスト方式で使うべきでしょう。
ほとんどのルールを除外する、のような使い方は避けるべきです。

ちなみに僕はいくら便利でも自動でコードが書き換えられる事に抵抗があるため自動整形は使用していませんが、同じ方法でできると思います！
ぜひチャレンジしてみてください！