PHP で遊ぶための環境を構築してみた

はじめに

4月に入り、PHP のスキルを上げ、開発スピードを上げよう!というチーム目標を立てました。

勉強は各自に任せて、だと何だか気持ち的な負担が高くなるような気がしたので、皆で PHP の勉強会をするようになりました。

そこで必要になったのが実行環境です。

本を読むだけでなく、実際に手を動かして試せる環境が欲しいなと思ったので、Docker の勉強がてら Docker + Composer + PHPUnit を使った環境構築に挑戦してみました。

それぞれを簡単にざっくり言うと・・・


準備するもの

ローカル環境に以下のものがインストールされている事

  • Docker

    • ※ 私の環境のバージョンは 18.09.2 でした
  • ディレクトリ構成

- test-php
    - app
        - src
            Calculator.php
        - tests
            SampleTest.php
    - docker
        - php7
            Dockerfile
    - html
        index.php
      composer.json
      docker-compose.yml

以下は各ファイルの内容です。

  • docker-compose.yml
version: '3'

services:
  test-php7:
      build: docker/php7
      container_name: 'test-php7'
      ports:
        - '8000:80'
      working_dir: /workspace
      volumes:
        - ./:/workspace
        - ./html:/var/www/html
  • docker/php7/Dockerfile
FROM php:7-apache

RUN apt-get update && apt-get install -y \
    # phpunit をインストールする時に必要
    zip

# root でのインストールを許可する設定
ENV COMPOSER_ALLOW_SUPERUSER 1;

# composer をインストールする
RUN curl -s http://getcomposer.org/installer | php \
    && mv composer.phar /usr/local/bin/composer
{
    "require-dev": {
        "phpunit/phpunit": "^8.1"
    },
    "scripts": {
        "test": [
            "phpunit"
        ]
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        }
    }
}

以下の PHP ファイルは単純なサンプルコードなので省略しています。

Calculator.php

<?php

namespace App\Src;

class Calculator
{
    /**
     * 足し算をする
     *
     * @param int $a
     * @param int $b
     * @return int
     */
    public static function add(int $a, int $b): int
    {
        return $a + $b;
    }
}

SampleTest.php

<?php

namespace App\Tests;

use App\Src\Calculator;
use PHPUnit\Framework\TestCase;

class SampleTest extends TestCase
{
    public function testSample()
    {
        // 期待する値
        $expected = 3;

        // テストしたい function を実行
        $result = Calculator::add(1, 2);

        $this->assertEquals($expected, $result);
    }
}


仮想環境の構築

コンテナを起動する

  • まずは、test-php ディレクトリでコンンテナを起動します。
    • -d はバックグラウンドで実行するためのオプションです。
    • これを実行する事で、PHP が実行でき、さらに Composer がインストールされた状態の仮想環境が構築されます。
$ docker-compose up -d

PHPUnit をインストールする

  • Composer を使って PHPUnit をコンテナ内にインストールします。
$ docker exec test-php7 composer update

※メモ docker exec を使い、コンテナ内のコマンド(composer update)を実行しました。

$ docker exec [コンテナ名] [コマンド]

テストを実行

  • ローカルからテストを実行する
$ docker exec test-php7 composer test -- app/tests

※ コンテナ内のコマンドにオプションを渡す時は、-- で一旦区切りを入れてから指定します。 この場合 $ docker exec test-php7 composer test app/tests はエラーになります。

テスト実行結果

> phpunit 'app/tests'
PHPUnit 8.1.2 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 247 ms, Memory: 4.00 MB

OK (1 test, 1 assertion)

これで、ローカルに PHP の実行環境を構築する事ができました。

今回の構築手順としては、

  1. PHP + Composer がインストールされた状態の仮想環境を Docker で用意する
  2. 仮想環境上の Composer を利用し、PHPUnit をインストールする

という大きく分けて2手間が必要な手順になりました。

Docker もまだまだ不明な点がたくさんあるので勉強しつつ、 今後の展望としては、DB(MySQL)のコンテナを用意して DB 接続を含めたテストを書いたりできるようにしてみたいなと思います。

ハマったポイント

1. PHPUnit をインストールする時に発生した警告!

コンテナの中に入って、手動で PHPUnit をインストールしてみた時に以下のようなメッセージが表示されました。

$ composer require phpunit/phpunit --dev
Do not run Composer as root/super user! See https://getcomposer.org/root for details

このメッセージが出ても中断される事なく PHPUnit はインストールされました。 どうやら root ユーザーでインストールを行う時に、セキュリティ的によろしくないよ、という事で警告が出ているようです。

www.itblog.jp

ではどう対応するのがベストなのか?

・・・

ローカルで動かすだけですし、、、すぐには分からなかったため、Dockerfile に以下の設定を付けました。 (メッセージが出なくなるだけで、根本的な解決ではないと思いますが)

# root でのインストールを許可する設定
ENV COMPOSER_ALLOW_SUPERUSER 1;

2. テスト実行時に Class Not Found!

PHP のクラスを作っている時には、IDEの補完が効いてくれていたので、つい一方のクラスからもう一方のクラスの参照が出来ているものと思ってしまいました。

実は以前にも同じような事にハマった事がありまして、エラーが出た時に「あぁあれね」と気付けたのですぐ解決できました。(一瞬ヒヤっとしましたが・・・)

※ 以前ハマった時の記事はこちら

解決するために、composer.json に以下のように autoload の設定を追加しました。

    "autoload": {
        "psr-4": {
            "App\\": "app/"
        }
    }

まとめ

  • 環境構築は不慣れなため、ちょっとしたコマンドを用意するだけでも時間がかかってしまいました。
  • 時間がかかってしまった分、達成感を味わえたと思います。
  • ひとまず動くところまでできたけれども、この構成で良いのか?という不安があります。
  • まずは第一歩という事で、これからDBのコンンテナ用意したり、色々試して拡張して行けたらいいなと思います。