Yum で複数バージョンの PHP を共存させる

# 概要
PHP の任意のバージョンを同一サーバー上に共存させる方法として phpenv や [phpbrew](https://github.com/phpbrew/phpbrew/blob/master/README.ja.md) 、 [php7dev](https://github.com/rlerdorf/php7dev) [^php7dev] などがあるが、ここでは Yum でインストールする方法を紹介する。
[^php7dev]: [VirtualBox + Vagrant で PHP7の実行環境をちゃちゃっと作る | バシャログ。](http://bashalog.c-brains.jp/15/06/08-100000.php)
## リポジトリ
* Remi's Repository
* The Software Collections (SCL) Repository
* IUS Repository
* Atomic Archive
* Webtatic Yum Repository

複数バージョンをインストールできる Yum リポジトリは上記の 5 つである。

基本的には PHP 5.4 以降のマイナーバージョンごとの最新版をインストールする形になる。PHP 5.3 以前や、リリースバージョンの違いをインストールしたい場合は phpenv などを利用するといいだろう。

**Remi's Repository** は 2012 年から Redhat 社で RHEL の PHP のバックポートを担当している Remi Collet 氏がメンテナンスしており、パッケージの豊富さから言ってもこれを選択するのが妥当だろう。 PHP 7.1 も用意されている。

# インストール
## 作業環境
ここでは VirtualBox 上で動作させている CentOS 7.2.1511 で検証している。

## Remi レポジトリのインストール
```bash
yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
yum install yum-utils
yum-config-manager --enable remi
```

`yum-utils` パッケージをインストールすると `yum-config-manager` コマンドが使えるようになる。
remi リポジトリはインストール直後はすべて無効になっているので、有効にする必要がある。

## PHP のインストール
```bash
for v in 54 55 56 70 71 ; do yum -y install php$v php$v-php-{gd,xml,mbstring,mysqlnd} ; done
for v in 54 55 ; do yum -y install php$v-php-pecl-{apc,memcached} ; done
for v in 56 70 71 ; do yum -y install php$v-php-{opcache,pecl-apcu,pecl-memcached} ; done
```

各バージョンはそれぞれ `php54` `php55` ... というパッケージ名になっている。非常に量が多くなるので `for` 文でまとめた。
必要なモジュールもあわせてインストールしておこう。なお、`php56` 以降は APC が OPCache + APCu になるなどパッケージ名に違いがあるので注意したい。

## バージョンの確認
```bash
for v in 54 55 56 70 71 ; do php$v -v ; echo \ ; done
```
```bash:Output
PHP 5.4.45 (cli) (built: Jun 23 2016 15:01:51)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies

PHP 5.5.37 (cli) (built: Jun 21 2016 13:53:45)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2015 Zend Technologies

PHP 5.6.23 (cli) (built: Jun 22 2016 07:42:11)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies

PHP 7.0.8 (cli) (built: Jun 22 2016 10:57:20) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.8, Copyright (c) 1999-2016, by Zend Technologies

PHP 7.1.0alpha3 (cli) (built: Jul  6 2016 10:49:24) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.1.0-dev, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.1.0alpha3, Copyright (c) 1999-2016, by Zend Technologies
```

この時点で PHP の各バージョンはインストールされている。

## php.ini の配置場所
```bash
for v in 54 55 56 70 71 ; do php$v --ini | grep Loaded | awk '{print $4}' ; done
```
```bash:Output
/opt/remi/php54/root/etc/php.ini
/opt/remi/php55/root/etc/php.ini
/opt/remi/php56/root/etc/php.ini
/etc/opt/remi/php70/php.ini
/etc/opt/remi/php71/php.ini
```

`php.ini` などの場所は上記の通り。 `php70` からパスが変わっているので注意。

## バージョンの切り替え
```bash
module load php54
php -v
```
```bash:Output
PHP 5.4.45 (cli) (built: Jun 23 2016 15:01:51)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies
```
```
module unload php54
php -v
```
```bash:Output
-bash: php: コマンドが見つかりません
```

`module load <モジュール名>` で切り替える。単体で切り替えるだけの場合はこれで充分だろう。

# URL で環境を切り替える

### php-fpm のインストール
```bash
for v in 54 55 56 70 71 ; do yum -y install php$v-php-fpm ; done
```

### php-fpm の設定
##### プロセスマネージャーの変更
###### 変更
```bash
for v in 54 55 56 ; do sed -i '/pm = /s/dynamic/ondemand/' /opt/remi/php$v/root/etc/php-fpm.d/www.conf ; done
for v in 70 71 ; do sed -i '/pm = /s/dynamic/ondemand/' /etc/opt/remi/php$v/php-fpm.d/www.conf ; done
```
###### 確認
```bash
for v in 54 55 56 ; do grep 'pm = ondemand' /opt/remi/php$v/root/etc/php-fpm.d/www.conf ; done
for v in 70 71 ; do grep 'pm = ondemand' /etc/opt/remi/php$v/php-fpm.d/www.conf ; done
```
##### listen のポート指定
###### 変更
```bash
for v in 54 55 56 ; do sed -i "s/9000/90$v/" /opt/remi/php$v/root/etc/php-fpm.d/www.conf ; done
for v in 70 71 ; do sed -i "s/9000/90$v/" /etc/opt/remi/php$v/php-fpm.d/www.conf ; done
```
###### 確認
```bash
for v in 54 55 56 ; do grep 'listen = 127' /opt/remi/php$v/root/etc/php-fpm.d/www.conf ; done
for v in 70 71 ; do grep 'listen = 127' /etc/opt/remi/php$v/php-fpm.d/www.conf ; done
```
### Apache の設定
```apache
cat << "_EOF_" > /etc/httpd/conf.d/remi.conf
    <VirtualHost *:80>
        ServerName php71
        <FilesMatch \.php$>
            SetHandler "proxy:fcgi://127.0.0.1:9071"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php70
        <FilesMatch \.php$>
            SetHandler "proxy:fcgi://127.0.0.1:9070"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php56
        <FilesMatch \.php$>
            SetHandler "proxy:fcgi://127.0.0.1:9056"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php55
        <FilesMatch \.php$>
            SetHandler "proxy:fcgi://127.0.0.1:9055"
        </FilesMatch>
    </VirtualHost>

    <VirtualHost *:80>
        ServerName php54
        <FilesMatch \.php$>
            SetHandler "proxy:fcgi://127.0.0.1:9054"
        </FilesMatch>
    </VirtualHost>
_EOF_
```
### SELinux の設定
```bash
for v in 54 55 56 70 71 ; do time semanage port -a -t http_port_t -p tcp 90$v ; done
```
1件あたり15秒前後かかるので気長に待つ。

### php-fpm の起動
```bash
for v in 54 55 56 70 71 ; do systemctl start php$v-php-fpm ; systemctl enable php$v-php-fpm ; done
```
### Apache の起動
```bash
systemctl start httpd && systemctl enable httpd
```
### サンプルファイルの作成
```bash
echo "PHP Version: <?php echo phpversion();" > /var/www/html/index.php
```
## hosts ファイルの書き換え
```bash:\Windows\System32\drivers\etc\hosts
192.168.56.101    php71 php70 php56 php55 php54
```
## ブラウザから確認
* http://php71/
* http://php70/
* http://php56/
* http://php55/
* http://php54/

# PHP関連記事
* [GitHubで人気の高いCMSランキング](http://qiita.com/bezeklik/items/45fa04b83792743b7cbf)
* [PHPのリリース日とサポート期限](http://qiita.com/bezeklik/items/72d1ff8393f66673e2bc)
* [CentOSのPHPは本当に安全か](http://qiita.com/bezeklik/items/0823b14789d96f847d09)
* [CentOSのPHPセキュリティパッチ履歴](http://qiita.com/bezeklik/items/dea228409f7aecd50c95)
* [Yum で任意のバージョンの PHP をインストールする](http://qiita.com/bezeklik/items/74106f3ed528584293c3)

# 参考リンク