DockerでPHPの環境構築をする方法　〜docker-compose.yml〜（PDOが使用できます）

PHP、Apache、MySQL、phpMyAdminをdocker-compose.ymlで一気に構築する。
なお、MySQLには`test`データベースがあり、`user`テーブルの中に、`username`と`email`のカラムがある。

#ディレクトリ構成

```
Desktop/docker
           ├html
           │  └index.php
           ├php
           │  ├Dockerfile
           │  └php.ini
           ├docker-compose.yml
           ├my.conf
```

デスクトップ上に`Docker`というディレクトリを作成し、その中に各ディレクトリ、ファイルを作成している。

＃各ファイルの中身

##html/index.php
PDOクラスで必要とするhostは、localhostではなくmysqlの任意でつけたコンテナ名を記載する。
ユーザ名とパスワードもdocker-compose.ymlで記載したものを記述する。

```php:index.php
<?php
function connect_db(){
    //ホスト名、データベース名、文字コードの３つを定義する
    $host = 'mysql5.7';
    $db = 'test';
    $charset = 'utf8';
    $dsn = "mysql:host=$host; dbname=$db; charset=$charset";

    //ユーザー名、パスワード
    $user = 'test';
    $pass = 'test';

    //オプション
    $options = [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ];

    try{

        //上のデータを引数に入れて、PDOインスタンスを作成
        $pdo = new PDO($dsn, $user, $pass, $options);

    }catch(PDOException $e){
        echo $e->getMessage();
    }

    //PDOインスタンスを返す
    return $pdo;
}

//データベースと接続して、PDOインスタンスを取得
$pdo = connect_db();

//実行したいSQLを準備する
$sql = 'SELECT * FROM user';
$stmt = $pdo->prepare($sql);

//SQLを実行
$stmt->execute();

//データベースの値を取得
$result = $stmt->fetchall();
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <?php
    foreach($result as $r){
        echo 'username: '. $r['username'];
        echo '<br>';
        echo 'email: '. $r['email'];
        echo '<hr>';
    }
    ?>
</body>
</html>
```

##php/Dockerfile
ベースイメージのphp:7.2-apacheはデフォルトではどうやらPDOクラスを使用できないらしいから、Dockerfileにて記載。

```dockerfile:Dockerfile
FROM php:7.2-apache
# PDOを使用できるようにする
RUN docker-php-ext-install pdo_mysql
```

##php/php.ini

```ini:php.ini
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
```

##docker-compose.yml

```yml:docker-compose.yml
version: '3'

services:
  php:
    build: ./php
    volumes:
      - ./php/php.ini:/usr/local/etc/php/php.ini
      - ./html:/var/www/html
    ports:
      - 8080:80
    container_name: php7.2

  mysql:
    image: mysql:5.7
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    volumes:
      - ./mysql:/var/lib/mysql
      - ./my.cnf:/etc/mysql/conf.d/my.cnf
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=test
      - MYSQL_USER=test
      - MYSQL_PASSWORD=test
      - "TZ=Asia/Tokyo"
    container_name: mysql5.7
    
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=mysql
      - PMA_USER=test
      - PMA_PASSWORD=test
    links:
      - mysql
    ports:
      - 4040:80
    volumes:
      - ./phpmyadmin/sessions:/sessions
    container_name: phpmyadmin
```

##my.cnf
デフォルトだと、文字コードがlatinになっているから、utf-8に変更するためのファイル

```my.cnf
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

[client]
default-character-set=utf8
```

#コンテナの作成と開始
それぞれのファイルに記述したら、ターミナルでDockerディレクトリの配下をカレントディレクトリとし、docker-composeコマンドを実行する。
docker-compose.ymlのある場所をカレントディレクトリとすること。

```terminal:terminal
docker-compose up -d
```

#動作確認
##webサーバ
`localhost:8080/index.php`にアクセスする。

##phpMyAdmin
`localhost:4040`にアクセスする。

#おまけ　コマンドメモ
##サービスの停止

```
docker-compose stop
```

##サービスの開始（既にコンテナが存在する場合）

```
docker-compose start
```

##コンテナの削除

```
docker-compose down
```

##イメージの一括削除

```
docker images -aq | xargs docker rmi
```