PHPアプリ開発をPhpStormでスムーズに始められるよう、設定ファイルとドキュメントを用意する

BASE株式会社 Product Dev Division ソフトウェアエンジニアの田中(@tenkoma)です。主にPHPアプリ開発を担当しています。

BASEでは、PHPアプリ開発で使うエディタに制限はありませんが、希望する人はPhpStormを使えます。 PhpStormは設定を全くしなくてもかなり快適に使えると思いますが、多少設定するとより快適になります。 この記事では主に、開発環境とIDEを連携させアプリケーション開発をスムーズに始めるため、以下の設定について紹介します。

  1. Xdebugと連携してリモートデバッグを可能にする
  2. PHPUnitと連携してテストをIDEから実行可能にする
  3. PHP_CodeSnifferを使ってコーディングスタイルを適用する
  4. EditorConfigを追加してコーディングスタイルを開発者で共有可能にする

Xdebugと連携してリモートデバッグを可能にする

BASEでは開発環境をDocker(docker-compose) を使って構築していて、環境構築に必要な手順を極力コードにしています。

PhpStormにはDocker環境と連携してリモートデバッグしたり、テストする機能があり、日々活用しています。

今回は以下のようなDockerの設定があり、対象のアプリケーションへWebアクセスが可能になっている状態である前提のもと、ブラウザからWebアクセスしたときに自動的にデバッグモードが起動し、IDE上で設定したブレークポイントで処理を止められるようにしてみます。 (実際のプロジェクトの開発環境を簡素化しています)

docker-compose.yml

# docker-compose.yml
version: '3'
services:
  php-cli:
    build: ./docker
    volumes:
      - ./:/var/www/html
      - ./docker/php.ini:/usr/local/etc/php/php.ini
    working_dir: /var/www/html
    ports:
      - "8080:80"
    expose:
      - "8080"
  composer:
    image: composer
    volumes:
      - ./:/app
      - ./docker/php.ini:/usr/local/etc/php/php.ini
    working_dir: /app

docker/php.ini

; docker/php.ini
; timezone
date.timezone = Asia/Tokyo

; error reporting
log_errors = On
error_log = /dev/stderr

; Xdebug
xdebug.remote_enable = On
xdebug.remote_autostart = On
xdebug.remote_connect_back = Off
; デバッグ接続先をホストOS( host.docker.internal )に向ける
xdebug.remote_host = host.docker.internal

docker/Dockerfile

# docker/Dockerfile
FROM php:7-apache

# Xdebug のインストールと有効化
RUN pecl install xdebug \
    && docker-php-ext-enable xdebug

ENV APACHE_DOCUMENT_ROOT /var/www/html/public

RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf

このファイルがリポジトリに含まれているとして、PhpStormでデバッグしてみましょう。 まずコンテナ群を起動します。(PhpStormでdocker-compose.yml を開き、緑矢印ボタンを押してもOK)

$ docker-compose up -d

デバッグするスクリプトを用意します。

<?php
// public/index.php
phpinfo();

3行目の phpinfo(); にブレークポイントを作成したらIDE右上のStart Listening for PHP Debug Connectionsをクリックして、http://localhost:8080/ にアクセスします。

f:id:tenkoma:20190821132949p:plain
Start Listening for PHP Debug Connectionsボタン

すると、「Incoming Connection from Xdebug」というダイアログが表示されますので、Acceptボタンをクリックします。すると、以下のように index.php の3行目で処理がブレークします。 (ブレークしない場合、ファイアーウォールの設定を見直したり、一時的にオフにして問題の切り分けが必要になります。)

f:id:tenkoma:20190821133048p:plain
index.php の3行目でブレークしているところ

PHPアプリリポジトリに docker-compose.yml を用意しておけば、Preferences を開いて設定しなくても、PhpStormでデバッグできました。 PhpStorm のデバッグツールでは条件付きブレークや、ブレークする代わりにPHPコード実行結果をデバッグコンソールにログをとる機能もあるので、 デバッグ連携できると開発が非常に楽になります。

BASEのプロジェクトでは、複数のリポジトリから共通のローカル環境を使うため、Docker環境を独立したリポジトリで管理しています。そのような場合は、ホストOS-コンテナ間のPath Mapping設定を docker-compose.yml から読み取ってくれないので別途設定が必要です。

PHPUnitと連携してテストをIDEから実行可能にする

IDEからテストを実行できると、ターミナルと行き来してテスト実行コマンドを入力しなくても良くなるため快適です。

前提として、以下の設定ファイルを用意します。

composer.json

{
  "name": "baseinc/sample-api-php",
  "autoload": {
    "psr-4": {
      "App\\": "src/"
    }
  },
  "autoload-dev": {
    "psr-4": {
      "Tests\\": "tests/"
    }
  },
  "require-dev": {
    "phpunit/phpunit": "^8.3",
    "squizlabs/php_codesniffer": "3.*"
  }
}

保存したら、PHPUnitをインストールします。

$ docker-compose run composer composer install

そして、テストファイルを追加してみます。

<?php
// tests/SampleTest.php
namespace Tests;

class SampleTest extends \PHPUnit\Framework\TestCase
{
    public function testSame(): void
    {
        $this->assertSame(0, "0");
    }
}

エディタの左側に緑矢印が表示されますが、まだテストは実行できません。

PhpStormでPHPUnitを使ったテストを実行するための設定

PhpStormからDockerコンテナ上でPHPUnitを実行させるのはいきなりは出来ません。どこのPHPインタプリタを使用させるのか、どのテストフレームワークを使用させるかをPhpStormに設定しなければなりません。 CLI Interpreter とTest Frameworksの設定をします。

  • 「Preferences」を開き、Languages & Frameworks > PHPにアクセス
  • 右パネルの CLI Interpreter:<no interpreter> になっているかと思いますが、右側の ... ボタンをクリック
  • 「CLI Interpreters」ダイアログが開いたら、左上の + ボタンから、From Docker, Vagrant, VM, Remote... 」を選択
  • 「Configure Remote PHP Interpreter」ダイアログが開いたら、Docker Compose 選択し、Service:php-cli に変更して OK をクリックして閉じる
  • 「CLI Interpreters」ダイアログが以下のような表示に変わったらOK

f:id:tenkoma:20190821133324p:plain
「CLI Interpreters」ダイアログ

  • 次にLanguages & Frameworks > PHP > Test Frameworks を選択
  • 右パネルで、+ ボタンをクリックし、PHPUnit by Remote Interpreter を選択
  • ポップアップダイアログでは php-cli (7.x.x) に切り替えて OK ボタンを選択
  • 詳細な設定が入力できるようになるので、 Path to Script:/var/www/html/vendor/autoload.php と入力し、 OKを押し、「Preferences」を閉じる

f:id:tenkoma:20190821133505p:plain
Languages & Frameworks > PHP > Test Frameworks

これで設定完了です。もし、 phpunit.xml.dist が用意されている場合は、 Default configuration file: をチェックし /var/www/html/phpunit.xml.dist を入力します。

緑矢印をクリックしてテストを実行すると、次のように結果が表示されます。 (前節でオンにした、IDE右上の Start Listening for PHP Debug Connections はオフにしたほうがいいみたいです。)

f:id:tenkoma:20190821133615p:plain
PHPUnitテスト結果が表示されたRunパネル

これでPHPUnit連携ができ、IDEから実行可能になりました。ショートカットキーから一発で実行することも出来ますし、デバッグ実行すれば設定したブレークポイントでブレークすることも可能です。 var_dump() によるプリントデバッグも手軽なのですが、実行途中の変数情報を一覧できたほうがもっと効率よくテストを書くことが出来るのでとてもおすすめです。

PHP_CodeSnifferを使ってコーディングスタイルを適用する

コーディングスタイル違反はCIで指摘するよう設定されていますが、コミット前に修正できると指摘されなくなり、開発しやすくなります。 (本当はコミット時に自動適用される設定を紹介したかったのですが、やってみると、コミットのソースに反映されてしまったので、IDEとの連携設定だけ紹介します)

1. phpcs, phpcbf のパスを設定する

  • 「Preferences」を開き、Languages & Frameworks > PHP > Test Frameworks > Quality Tools を開く
  • Configuration: 右側の ... ボタンをクリック
  • PHP Code Sniffer path:/path/to/your/project/vendor/bin/phpcs を入力
  • PHP Code beautifier and Fixer Settings - Path to phpcbf:/path/to/your/project/vendor/bin/phpcbf を入力
  • OK ボタンを押して、「Preferences」を閉じる

f:id:tenkoma:20190821133706p:plain
Code Snifferダイアログ

2. コーディングスタイルルールを選択する

  • 「Preferences」を開き、Editor > Inspections を選択
  • PHP Code Sniffer validation にチェックを付ける
  • Coding standard: の右側の更新ボタンをクリックすると、リストが更新されるので、PSR2を選択

f:id:tenkoma:20190821133806p:plain
Editor > Inspections

以上で設定完了です。この状態で以下のコードのコーディングスタイルを修正してみます。

<?php
// src/Sample.php
class Sample{
    public function test(): void{
        if ($_SERVER['HTTPS']==='on') {header("Location: https://{$_SERVER['HTTP_HOST']}");}
    }
}

メニューバーから Code > Code Cleanup... を選ぶと、以下のように変更されます。

<?php
// src/Sample.php
class Sample
{
    public function test(): void
    {
        if ($_SERVER['HTTPS']==='on') {
            header("Location: https://{$_SERVER['HTTP_HOST']}");
        }
    }
}

EditorConfig設定を追加してインデントを自動調整する

.editorconfig ファイルを用意しておくと、エディタのインデント設定を無視してそれに従ってくれます。

.editorconfig

; .editorconfig
root = true

[*]
end_of_line = lf
insert_final_newline = true

[*.php]
charset = utf-8
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

PHPファイルを保存すると、行末尾のスペースを削除したり、最終行末尾に改行が挿入されるのがわかります。 自動化されていないとバラバラになりがちなので便利です。

以前のバージョンでは、プラグインをインストールする必要がありましたが、2019.2でバンドルされるようになったので、手間が減りました。

設定ドキュメントを書く

上記で紹介したように、PhpStormに限定されないようなDocker環境/PHPUnit/PHP_CodeSniffer などの設定ファイルはリポジトリで共有していますが、PhpStormの設定については管理してないので、社内情報共有ツール(Kibela)にドキュメントを書いて共有しています。例えば以下のようなドキュメントがあります。

  • PHPプロジェクト向けIDE PhpStorm 推奨設定
  • PHPUnit と IDE(PhpStorm) を連携させて、PHPアプリ開発を楽にしよう
  • PhpStorm おすすめプラグイン
  • PhpStorm + Xdebug (Remote Debug) CLI編

プロジェクトの .idea ディレクトリの特定のファイルをリポジトリに含めれば、もっと環境構築をスムーズにできそうですが、PhpStormにロックインさせすぎるのもどうかな、という気持ちがあり、やっていません。スクリーンショット付きで説明したような手順についてはドキュメントで共有しています。

まとめ

PhpStorm で開発がしやすくなるようDocker環境、デバッグ、テストの設定を用意したり、情報共有ツールで、PhpStormの設定ドキュメントを共有する話を紹介しました。