Visual Studio Code - PHPの開発環境を VSCode と Vagrant + Docker で構築する時のツール類

# はじめに

PHPを使った開発ではいつも Visual Studio Code を使っています。
プラグインには特にこだわりはないのですが、複数人でのチーム開発を意識すると、何かしら有効なツールがあるのではないかと、以前から興味を持っていました。

そこでPHPに関する静的解析を行うツールを探してみると、想定していた以上に多くのツールが存在しているようです。
今回はその中でも、特に必要だと思われるツールを、 Visual Studio Code に組み込む方法について、まとめてゆきます。


# 基本情報

## PHP の解析ツール

最初に、特定の IDE には依存しない PHP の解析ツールについてまとめます。

### 静的解析ツール

まずは「[静的コード解析](https://ja.wikipedia.org/wiki/%E9%9D%99%E7%9A%84%E3%82%B3%E3%83%BC%E3%83%89%E8%A7%A3%E6%9E%90)」に関連するツールについてです。

#### Bugs finders

PHP において、バグに繋がるソースコード上の問題を検出するツールには、以下のようなものがあります。

- [PHPMD (PHP Mess Detector)](https://github.com/phpmd/phpmd)
- [PHPStan (PHP Static Analysis Tool)](https://github.com/phpstan/phpstan)
- [PhpCodeFixer](https://github.com/wapmorgan/PhpCodeFixer)
- [PHPCPD (PHP Copy past detector)](https://github.com/sebastianbergmann/phpcpd)
- [PHPMND (PHP Magic Number Detector)](https://github.com/povils/phpmnd)
- [churn-php](https://github.com/bmitch/churn-php)
- [PHPUnit and the CRAP(Change Risk Anti-Patterns) metric](https://github.com/sebastianbergmann/phpunit)

|何|概要|採用？|
|:--|:--|:--:|
|PHPMD|PHPの潜在的なバグを検知出来る|yes|
|PHPStan|コードを実行せずにエラーを検出する|yes|
|PhpCodeFixer|ソースコードの複雑さを検査する|yes|
|PHPCPD|ソースコード内のコピペを検出する|yes|
|PHPMND|マジックナンバーを検出する|no|
|churn-php|リファクタリングをサポートする|yes|
|PHPUnit|単体テストを実現する|yes|

#### Coding standards

PHP で記載されたソースコードの記法をレビュするツールには、以下のようなものがあります。

- [PHPCS (PHP CodeSniffer)](https://github.com/squizlabs/PHP_CodeSniffer)
- [PHPCheckstyle](https://github.com/PHPCheckstyle/phpcheckstyle)
- [PHP formatter](https://github.com/mmoreram/php-formatter)

|何|概要|採用？|
|:--|:--|:--:|
|PHPCS|コーディングスタイルのチェックを行う|yes|
|PHPCheckstyle|コーディングスタイルのチェックを行う|no|
|PHP formatter| PSRに従ってコードをフォーマットする|no|

#### Fixers

PHP で記載されたソースコードを自動で修正するツールには、以下のようなものがあります。

- [PHP-CS-Fixer (PHP Coding Standards Fixer)](https://github.com/FriendsOfPHP/PHP-CS-Fixer)

|何|概要|採用？|
|:--|:--|:--:|
|PHP-CS-Fixer|PSRに従ってコードをフォーマットする|yes|

#### Metrics

PHP で記載されたソースコードを計測し、コードの複雑さや行数を出力するツールには、以下のようなものがあります。

- [PhpLoc](https://github.com/sebastianbergmann/phploc)
- [PhpMetrics](https://github.com/phpmetrics/PhpMetrics)
- [dePHPend](https://github.com/mihaeu/dephpend)

|何|概要|採用？|
|:--|:--|:--:|
|PhpLoc|PHPプロジェクトの構造をスキャンする|no|
|PhpMetrics|メトリクスをHTMLで出力する|yes|
|dePHPend|ソースコードを分析し依存関係を検査する|no|

#### Misc (その他)

静的解析からは少し外れますが、以下のような phpDocumentor で ドキュメントを自動生成する為に、PHPDocの書式に従ってコメントを記載します。

- [phpDocumentor](https://www.phpdoc.org/)
- [PHPDoc](https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md)

### 動的解析ツール

次は「動的コード解析」に関連するツールについてです。

#### UnitTest

PHP の xUnitツールといえば、PHPUnitです。

- [PHPUnit](https://phpunit.de/)

#### DebugTrace

PHP の開発で ブレークポイント を張って、スタックを確認することが出来る PHP の拡張モジュールです。

- [Xdebug](https://xdebug.org/)

## Visual Studio Code のプラグイン

最後に、 Visual Studio Code のプラグインで前述のツールに関連しそうなものを列挙します。

- [PHP IntelliSense](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-intellisense)
- [PHP Intelephense](https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client)
- [PHP Debug](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug)
- [phpcs](https://marketplace.visualstudio.com/items?itemName=ikappas.phpcs)
- [php cs fixer](https://marketplace.visualstudio.com/items?itemName=junstyle.php-cs-fixer)
- [PHP Mess Detector](https://marketplace.visualstudio.com/items?itemName=ecodes.vscode-phpmd)
- [PHP DocBlocker](https://marketplace.visualstudio.com/items?itemName=neilbrayfield.php-docblocker)
- [vscode-phpstan](https://marketplace.visualstudio.com/items?itemName=calsmurf2904.vscode-phpstan)

この中から、今回使用しようとしているツール と Visual Studio Code を関連付けると以下のようになりました。
Visual Studio Code に組み込めるものもあれば、 composer で直接ソースコードへインストールし、コマンド実行で確認を行うものもあります。

|何|プラグイン|補足|
|:--|:--|:--|
|-|[PHP Intelephense](https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client)|PHPのサジェスト機能など。<br>特筆した設定は不要|
|PHPMD|[PHP Mess Detector](https://marketplace.visualstudio.com/items?itemName=ecodes.vscode-phpmd)|プラグインのインストールに加え、composerで<br>ソースコードにphpmdの追加が必要そうだが、<br>詳細を確認出来ていない|
|PHPStan|-|composerでソースコードに導入|
|PhpCodeFixer|-|composerでソースコードに導入|
|PHPCPD|-|composerでソースコードに導入|
|churn-php|-|composerでソースコードに導入|
|PHPUnit|-|composerでソースコードに導入|
|PHPCS|[phpcs](https://marketplace.visualstudio.com/items?itemName=ikappas.phpcs)|プラグインのインストールに加え、composerで<br>ソースコードにPHP_CodeSnifferを追加する。|
|PHP-CS-Fixer|[php cs fixer](https://marketplace.visualstudio.com/items?itemName=junstyle.php-cs-fixer)|プラグインのインストールに加え、composerで<br>ソースコードにphp cs fixer を追加する。|
|PhpMetrics|-|composerでソースコードに導入|
|PHPDoc|[PHP DocBlocker](https://marketplace.visualstudio.com/items?itemName=neilbrayfield.php-docblocker)|特筆した設定は不要。|
|Xdebug|[PHP Debug](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug)|設定が必要|
|-|PHP Namespace Resolver|特筆した設定は不要。|

Xdebug 以外については、 Visual Studio Code への プラグインのインストールか、 composer を用いたソースコードに導入、またはその両方の手段によって、導入が可能なようです。

# 構築手順

## 概要

前章までの調査と選別の結果を踏まえて環境を構築した際のソフトウェア・スタックは以下のようになりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79222/e80b0956-edc9-0019-9f9a-db241224c14c.png)

かなりリッチな構成になってしまいました。
実際に動かしてみると、特定の状況で Visual Studio Code がフリーズしてしまいました。
コードのスタイルチェックなどは、どれか消してしまっても良いかもしれません。

## 手順

前節の構成を構築する手順を記載してゆきます。
なお、以降で使用する構築用のスクリプトは GitHub 上に存在する以下の2つのリポジトリを使用しています。

- [anfangd/docker-on-vagrant-script - GitHub](https://github.com/anfangd/docker-on-vagrant-script)
- [anfangd/laravel-by-docker-script - GitHub](https://github.com/anfangd/laravel-by-docker-script)

PHP のバージョンや、 Xdebug の設定、 composer のインストールなど、細かい設定はすべて上記のスクリプトに記載していますので、環境をカスタムした場合や、設定情報を確認したい場合はそちらを参照してください。

### Visual Studio Code へのプラグインの導入

Visual Studio Code への導入方法については記載するまでもないと思います。
以下のプラグインを導入します。

- PHP Namespace Resolver
- PHP Intelephense
- PHP Mess Detector
- phpcs
- php cs fixer
- PHP DocBlocker
- PHP Debug

### Vagrant + Docker で PHP実行環境を構築

ホストOS 上で以下のコマンドを実行することで、 Docker と docker-compose が入った CentOS 7 を構築します。

```bash:@HostOS
// Vagrant のプラグインをインストールする
$ vagrant plugin install vagrant-vbguest
$ vagrant plugin install vagrant-proxyconf

// GitHub から Vagrantfile と provision.sh を取得する
$ git clone https://github.com/anfangd/docker-on-vagrant-script.git
$ cd docker-on-vagrant-script

// Vagrant の起動する
$ vagrant up

// 仮想環境へ ssh でアクセスする
$ vagrant ssh
```

起動した仮想環境内で、 Docker と docker-compose をコマンド操作できるか確認します。

```bash:@VirtualOS
// docker の動作確認をする
$ docker run hello-world

// docker のバージョン確認をする
$ docker --version
Docker version 18.06.1-ce, build e68fc7a

// docker-compose のバージョン確認をする
$ docker-compose --version
docker-compose version 1.17.1, build 6d101fb
```

仮想環境内で、 PHP実行環境 や nginx などのコンテナを構築するスクリプトを取得し、 docker-compose でコンテナを構築します。

```bash:@VirtualOS
// HostOS とファイル同期が取れるよう、 /vagrant へ移動
cd /vagrant

// GitHub から docker-compose 用の スクリプトを取得する
$ git clone https://github.com/anfangd/laravel-by-docker-script.git

// 取得したスクリプトをビルドして、docker-compose で コンテナを起動する
$ cd laravel-by-docker-script
$ docker-compose build
$ docker-compose up -d
```

### Visual Studio Code で PHP Debug の設定

Visual Studio Code の [デバッグ] > [構成の追加] から、 PHP の構成を追加します。
構成は以下のようになりました。

```json:.vscode/launch.json
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9001,
            "stopOnEntry": true,
            "log": true,
            "pathMappings": {
                "/src": "${workspaceRoot}"
            }
        },
        {
            "name": "Launch currently open script",
            "type": "php",
            "request": "launch",
            "program": "${file}",
            "cwd": "${fileDirname}",
            "port": 9000
        }
    ]
}
```

### composer でツールをプロジェクトにインストール

Vagrant 上に Docker で構築した PHP の実行環境にアクセスし、 Laravel をインストールしたあと、各ツールを composer でインストールします。
なお、DBへの接続設定などについては、以下を参照してみてください。

- [docker - ローカル開発環境の構築 / Laravel on Vagrant + VirtualBox with Docker - Qiita](https://qiita.com/anfangd/items/8c57f3d753117ea288b9)

```bash:@PHPContainer_on_VirtualOS
// laravel でプロジェクトを作成する
$ docker-compose exec php laravel new sample

// 各ツールをインストールする
$ composer require --dev phpstan/phpstan
$ composer require --dev sebastian/phpcpd
$ composer require --dev bmitch/churn-php
$ composer require --dev "squizlabs/php_codesniffer=*"
$ composer require --dev friendsofphp/php-cs-fixer
$ composer require --dev phpmetrics/phpmetrics
```

## まとめ

ここまで設定を行うことで、 Visual Studio Code でコードスタイルのチェックなどを効率的に実施することが出来ます。

また、 **Visual Studio Code にプラグインがなく、 composer でインストールしたもの**については、**各ツールに従ったコマンドを実行することで、メトリクスの出力やコードの解析を行う**ことが出来ます。こちらの**詳細については、それぞれの GitHub の README を参照**してみてください。

Xdebug については、Docker上のプログラムが実行された際に、 Visual Studio Code で詳細情報をキャッチすることが出来る設定は終わっています。 **Visual Studio Code で 「デバッグを開始」し、ソースコードの直接実行か、Webブラウザで対象のプログラムへアクセスすることで、 Xdebug を使用したデバッグを行う**ことが出来ます。

以下は、 info.php にブレークポイントを設定し、 Chrome で対象のサイトを指定して表示しようとすると、自動で　Visual Studio Code が表示され、ブレークポイントを作成した箇所から、ステップ実行などを行うことが出来ます。

![Nov-04-2018 23-20-36.gif](https://qiita-image-store.s3.amazonaws.com/0/79222/95da8dd7-bc0b-b605-9f59-627e4c3daa03.gif)

上記の他、Vagrant 上の Docker コンテナ内で、PHPプログラムを直接実行（ `php sample.php` など ）でも同様にデバッグを行うことが出来ますので、状況に応じて、適切な方法で確認をしてみてください。

# 終わりに

この調査を始めるまでは漠然と、**「チームでソースコードをチェックするには、何かしらツールを導入したほうが良いし、ツールの導入くらいは簡単だろう」**という甘い考えでした。
ただ、実際に導入を検討しながら作業を進めると、まず**ツールの幅広さ**があり、その上で、**現在の開発環境へ適用する為の構成の検討や詳細な設定**など、**かなり面倒な作業ばかり**でした。

また、実際に構築してみると、ツールが原因か、 **Visual Studio Code の動作がもっさり**することが増え、チェックと引き換えに、**スピードを少し失った気がします**。

ただしその分、 Visual Studio Code でコードを記載する段階で、**ソースコードの記法を制限**し、**自動的にチェックを行うことが出来る**ので、やはり**複数人で開発する時には役に立つ設定も多い**と感じています。

もう少し**ブラッシュアップが必要そう**ですが、**ここをベースにもう少し良い構成に**して行ければと思います。

# 参考

- [Visual Studio Code で快適な PHP コーディングを行う - エレパ スタッフブログ](https://www.elp.co.jp/staffblog/?p=5620)
- [PHPプログラミングも快適に！ VS Codeの二大拡張機能 (1/3) - @IT](http://www.atmarkit.co.jp/ait/articles/1809/11/news028.html)
- [Visaul Studio Code で PHP、インテリセンスとデバッグ - Qiita](https://qiita.com/diconran/items/6caed6b15cdda23c9933)
- [Laravelで気持ちよく開発をするための拡張機能のまとめ - Qiita](https://qiita.com/motuo/items/5c9b24606ef75535f882)
- [VSCodeのDocker接続先をVagrantで起動したDockerサーバにする - Qiita](https://qiita.com/chakimar/items/83a562d1e4ba768576d8)
- [vagrant+virtualbox+ubuntu上のdocker上のphp+apacheのxdebug+vscodeについてハマったメモ - Qiita](https://qiita.com/hibohiboo/items/32a9635e62d0bf129a22)
- [Visual Studio CodeとVagrantを使った開発環境の構築 - プログラミングガール](http://hana-ori.hatenablog.com/entry/2018/04/15/172353)
- [vagrant-docker-compose プラグインの使い方 - Qiita](https://qiita.com/noobar/items/eedf1235c3fbd9744b76)
- [2018年のPHPDoc事情とPSR-5 - Qiita](https://qiita.com/tadsan/items/72b02339d12120ca37d7)
- [【初心者向】Visual Studio Codeでphp cs fixerを設定する方法 - モノグサにお灸](https://monoxa.net/2018/03/%E3%80%90%E5%88%9D%E5%BF%83%E8%80%85%E5%90%91%E3%80%91visual-studio-code%E3%81%A7php-cs-fixer%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/)
- [Visual Studio CodeのためのPHP_CodeSnifferであるphpcsを使ってコーディング規約をチェック - aipercent.net](https://aipercent.net/vscode/install-phpcs/)
- [VSCodeでphpcsのエラーメッセージが出る - Qiita](https://qiita.com/segur/items/f86427ca6e5d6fae0916)
- [[PHP]Visual Studio Codeを使ってphpcsによるPSR-2規約チェックを行う方法 - akamist blog](https://akamist.com/blog/archives/293)
- [PHPMDを使ってPHPのコードを綺麗にしよう - Sider Blog](https://blog-ja.sideci.com/entry/2017/06/27/110000)
- [Vagrant(+Docker) 上のPHPアプリをデバッグ実行する - Qiita](https://qiita.com/xanagi/items/b127ed3e5476cfd8eda7)
- [Dockerで構築したPHP環境をxdebugでデバッグ（vscode） - Qiita](https://qiita.com/gigosa/items/90431be7a6a79db78480)
- [Dockerで古いPHP(5.x)のXdebugを組み込んだデバッグ環境を構築する - Qiita](https://qiita.com/yoskeoka/items/c2801a20496851e3ace6)
- [Laravelで気持ちよく開発をするための拡張機能のまとめ - Qiita](https://qiita.com/motuo/items/5c9b24606ef75535f882)