複数のバージョンの PHP を切り替えて使う

この投稿では、複数の PHP のバージョンを CentOS 7 上で、適宜 “切り替えて” 使用することを念頭にしている。

つまり、異なるバージョンの PHP を同時に稼働させる目的ではないことに注意。

## remi リポジトリを追加する

初期のリポジトリでインストールできる PHP のバージョンは 5.4.x 系になるため、これよりも新しい PHP を使用するために、第三者のリポジトリ、remiリポジトリを登録してインストールする。

```
$ sudo yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```

remi リポジトリの良い点は、新しい PHP のバージョンをインストールできることの他に、複数のバージョンをインストールしても共存できるように各バージョンの設定ファイルを分けてくれる点にある。

## PHP 5.6 7.2 7.3 をインストールしてみる

```
$ for v in 56 72 73 ; do sudo yum -y install php$v php$v-php-{gd,xml,mbstring,mysqlnd,opcache,pecl-apcu,common,fpm,embedded,pear} ; done
```

```for v in 56 72 73``` に記述してある番号を、インストールしたい PHP のバージョンに変更することができます。今回は PHP 5.6 7.2 7.3 をインストールします。```php$v-php-{gd,xml,mbstring,mysqlnd,opcache,pecl-apcu,common,fpm,embedded}}``` は前記に記した各バージョンのモジュールなどをインストールします。ここは適宜、必要なモジュールを追加したりして変更してください。

## インストールされた各バージョンのファイルについて

### 各ファイルの本体の場所
```
$ ls -l /opt/remi/
total 0
dr-xr-xr-x. 3 root root 32 Feb 15 12:17 php56
dr-xr-xr-x. 3 root root 32 Feb 15 12:18 php72
dr-xr-xr-x. 3 root root 32 Feb 15 12:18 php73
```

基本的には /opt/remi 以下のディレクトリにインストールされたファイルが保存されています。

### 実行バイナリのパス

```
$ ls -l /usr/bin/ | grep php
lrwxrwxrwx. 1 root root        32 Feb 15 12:18 php56 -> /opt/remi/php56/root/usr/bin/php
lrwxrwxrwx. 1 root root        36 Feb 15 12:18 php56-cgi -> /opt/remi/php56/root/usr/bin/php-cgi
lrwxrwxrwx. 1 root root        33 Feb 15 12:18 php56-pear -> /opt/remi/php56/root/usr/bin/pear
lrwxrwxrwx. 1 root root        38 Feb 15 12:18 php56-phar -> /opt/remi/php56/root/usr/bin/phar.phar
lrwxrwxrwx. 1 root root        32 Feb 15 12:18 php72 -> /opt/remi/php72/root/usr/bin/php
lrwxrwxrwx. 1 root root        36 Feb 15 12:18 php72-cgi -> /opt/remi/php72/root/usr/bin/php-cgi
lrwxrwxrwx. 1 root root        36 Feb 15 12:18 php72-pear -> /opt/remi/php72/root/usr/bin/pear
lrwxrwxrwx. 1 root root        38 Feb 15 12:18 php72-phar -> /opt/remi/php72/root/usr/bin/phar.phar
lrwxrwxrwx. 1 root root        32 Feb 15 12:32 php73 -> /opt/remi/php73/root/usr/bin/php
lrwxrwxrwx. 1 root root        36 Feb 15 12:32 php73-cgi -> /opt/remi/php73/root/usr/bin/php-cgi
lrwxrwxrwx. 1 root root        36 Feb 15 12:32 php73-pear -> /opt/remi/php73/root/usr/bin/pear
lrwxrwxrwx. 1 root root        38 Feb 15 12:32 php73-phar -> /opt/remi/php73/root/usr/bin/phar.phar
```

前記の /opt/remi 以下に保存された実行ファイルに対して、/usr/bin 以下にシムリンクが生成されています。

```
$ /usr/bin/php73 -v
PHP 7.3.2 (cli) (built: Feb  5 2019 13:10:03) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.2, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.2, Copyright (c) 1999-2018, by Zend Technologies
```

バージョンを指定する必要がありますが、このように通常のパスから実行することができます。

### Apache 用の PHP モジュール

```
$ sudo find /opt/remi/ -type f -name libphp*
/opt/remi/php56/root/usr/lib64/libphp5-5.6.so
/opt/remi/php72/root/usr/lib64/libphp7-7.2.so
/opt/remi/php73/root/usr/lib64/libphp7-7.3.so
```

※ Apache 用のモジュールをインストールするには、php-common が必要になります。

### php-fpm 関連

```
$ sudo find /opt/remi/ -type f -name php-fpm
/opt/remi/php56/root/etc/sysconfig/php-fpm
/opt/remi/php56/root/usr/sbin/php-fpm
/opt/remi/php72/root/usr/sbin/php-fpm
/opt/remi/php73/root/usr/sbin/php-fpm
```

### php.ini など設定ファイル関連

PHP 5.x 系と PHP 7.x 系で、保存される設定ファイルのディレクトリが変更されていることに注意。

PHP 7.x の場合は

```
$ sudo find /etc/opt/remi/ -type f -name php.ini
/etc/opt/remi/php72/php.ini
/etc/opt/remi/php73/php.ini
$ sudo find /etc/opt/remi/ -type f -name *.conf
/etc/opt/remi/php72/php-fpm.conf
/etc/opt/remi/php72/php-fpm.d/www.conf
/etc/opt/remi/php73/php-fpm.conf
/etc/opt/remi/php73/php-fpm.d/www.conf
```

PHP 5.x の場合は

```
$ sudo find /opt/remi/ -type f -name php.ini
/opt/remi/php56/root/etc/php.ini
$ sudo find /opt/remi/ -type f -name *.conf
/opt/remi/php56/root/etc/pear.conf
/opt/remi/php56/root/etc/php-fpm.conf
/opt/remi/php56/root/etc/php-fpm.d/www.conf
```

### php-fpm の起動設定

インストール時は systemctl には登録されているが、サービス無効化されているので、必要なバージョンの php-fpm を有効化する

```
$ sudo systemctl list-unit-files --type=service | grep php
php56-php-fpm.service                         disabled
php72-php-fpm.service                         disabled
php73-php-fpm.service                         disabled
```

## alternatives コマンドで PHP のバージョンを切り替える

yum でインストールした PHP なので、管理もシステム内のエコシステムで完結したいところです。

alternatives はシンボリックリンクを使用して、デフォルトのコマンドを管理します。通常はインストール時にすでに alternatives がインストールされていて、使用できる状態になっています。

```
$ alternatives --list
libnssckbi.so.x86_64    auto    /usr/lib64/pkcs11/p11-kit-trust.so
ld      auto    /usr/bin/ld.bfd
mta     auto    /usr/sbin/sendmail.postfix
```

ここに PHP を管理できるようにします。

まずは、インストールしたバージョン毎の必要なファイル等の場所を確認してから、設定をします。
今回は次のように設定をしました。

```
$ sudo update-alternatives \
--install /usr/bin/php                       php     /opt/remi/php72/root/usr/bin/php 10    \
--slave   /usr/bin/php-cgi                   php-cgi /opt/remi/php72/root/usr/bin/php-cgi   \
--slave   /usr/bin/pear                      pear    /opt/remi/php72/root/usr/bin/pear      \
--slave   /usr/bin/phar.phar                 phar    /opt/remi/php72/root/usr/bin/phar.phar \
--slave   /usr/lib64/httpd/modules/libphp.so libphp  /opt/remi/php72/root/usr/lib64/libphp7-7.2.so

$ sudo update-alternatives \
--install /usr/bin/php                       php     /opt/remi/php56/root/usr/bin/php 20    \
--slave   /usr/bin/php-cgi                   php-cgi /opt/remi/php56/root/usr/bin/php-cgi   \
--slave   /usr/bin/pear                      pear    /opt/remi/php56/root/usr/bin/pear      \
--slave   /usr/bin/phar.phar                 phar    /opt/remi/php56/root/usr/bin/phar.phar \
--slave   /usr/lib64/httpd/modules/libphp.so libphp  /opt/remi/php56/root/usr/lib64/libphp5-5.6.so

$ sudo update-alternatives \
--install /usr/bin/php                       php     /opt/remi/php73/root/usr/bin/php 30    \
--slave   /usr/bin/php-cgi                   php-cgi /opt/remi/php73/root/usr/bin/php-cgi   \
--slave   /usr/bin/pear                      pear    /opt/remi/php73/root/usr/bin/pear      \
--slave   /usr/bin/phar.phar                 phar    /opt/remi/php73/root/usr/bin/phar.phar \
--slave   /usr/lib64/httpd/modules/libphp.so libphp  /opt/remi/php73/root/usr/lib64/libphp7-7.3.so
```
設定された内容は次のコマンドで確認できます。

```
$ alternatives --list
libnssckbi.so.x86_64    auto    /usr/lib64/pkcs11/p11-kit-trust.so
ld      auto    /usr/bin/ld.bfd
mta     auto    /usr/sbin/sendmail.postfix
php     manual  /opt/remi/php72/root/usr/bin/php
```

CentOS 7 の場合は設定ファイルは /var/lib/alternatives 以下にあります。

```
$ ls -l /var/lib/alternatives/
total 16
-rw-r--r--. 1 root root  57 Feb 14 15:25 ld
-rw-r--r--. 1 root root 101 Feb 14 15:28 libnssckbi.so.x86_64
-rw-r--r--. 1 root root 689 Feb 14 15:29 mta
-rw-r--r--. 1 root root 707 Feb 16 15:51 php
```

設定ファイルは次のように記述されていますので、いざというときは自分で修正をします。

```
$ cat /var/lib//alternatives/php 
manual
/usr/bin/php
pear
/usr/bin/pear
phar
/usr/bin/phar.phar
php-cgi
/usr/bin/php-cgi
libphp
/usr/lib64/httpd/modules/libphp.so

/opt/remi/php72/root/usr/bin/php
10
/opt/remi/php72/root/usr/bin/pear
/opt/remi/php72/root/usr/bin/phar.phar
/opt/remi/php72/root/usr/bin/php-cgi
/opt/remi/php72/root/usr/lib64/libphp7-7.2.so
/opt/remi/php56/root/usr/bin/php
20
/opt/remi/php56/root/usr/bin/pear
/opt/remi/php56/root/usr/bin/phar.phar
/opt/remi/php56/root/usr/bin/php-cgi
/opt/remi/php56/root/usr/lib64/libphp5-5.6.so
/opt/remi/php73/root/usr/bin/php
30
/opt/remi/php73/root/usr/bin/pear
/opt/remi/php73/root/usr/bin/phar.phar
/opt/remi/php73/root/usr/bin/php-cgi
/opt/remi/php73/root/usr/lib64/libphp7-7.3.so
```

### PHP のバージョンを切り替えてみる

下記の実行例の場合は、PHP 7.2 から PHP 7.3 に切り替えています。

バージョンを切り替えたときは、<span style="color: red;">Apache や php-fpm の再起動が必要になる場合があります</span>。PHP のバージョンを切り替えたときは、変更を適宜反映させるのに必要な作業を実行してください。

```
$ php -v
PHP 7.2.15 (cli) (built: Feb  5 2019 18:05:51) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.15, Copyright (c) 1999-2018, by Zend Technologies
$ sudo alternatives --config php

There are 3 programs which provide 'php'.

  Selection    Command
-----------------------------------------------
 + 1           /opt/remi/php72/root/usr/bin/php
   2           /opt/remi/php56/root/usr/bin/php
*  3           /opt/remi/php73/root/usr/bin/php

Enter to keep the current selection[+], or type selection number: 3
$ php -v
PHP 7.3.2 (cli) (built: Feb  5 2019 13:10:03) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.2, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.2, Copyright (c) 1999-2018, by Zend Technologies
```

### alternatives が管理するシムリンク

alternarives が管理するシムリンクは次のようになっています。

```
$ ls -l /etc/alternatives/
total 0
lrwxrwxrwx. 1 root root 15 Feb 14 15:25 ld -> /usr/bin/ld.bfd
lrwxrwxrwx. 1 root root 34 Feb 14 15:28 libnssckbi.so.x86_64 -> /usr/lib64/pkcs11/p11-kit-trust.so
lrwxrwxrwx. 1 root root 45 Feb 16 16:05 libphp -> /opt/remi/php73/root/usr/lib64/libphp7-7.3.so
lrwxrwxrwx. 1 root root 26 Feb 14 15:29 mta -> /usr/sbin/sendmail.postfix
lrwxrwxrwx. 1 root root 40 Feb 14 15:29 mta-aliasesman -> /usr/share/man/man5/aliases.postfix.5.gz
lrwxrwxrwx. 1 root root 22 Feb 14 15:29 mta-mailq -> /usr/bin/mailq.postfix
lrwxrwxrwx. 1 root root 38 Feb 14 15:29 mta-mailqman -> /usr/share/man/man1/mailq.postfix.1.gz
lrwxrwxrwx. 1 root root 27 Feb 14 15:29 mta-newaliases -> /usr/bin/newaliases.postfix
lrwxrwxrwx. 1 root root 43 Feb 14 15:29 mta-newaliasesman -> /usr/share/man/man1/newaliases.postfix.1.gz
lrwxrwxrwx. 1 root root 23 Feb 14 15:29 mta-pam -> /etc/pam.d/smtp.postfix
lrwxrwxrwx. 1 root root 22 Feb 14 15:29 mta-rmail -> /usr/bin/rmail.postfix
lrwxrwxrwx. 1 root root 25 Feb 14 15:29 mta-sendmail -> /usr/lib/sendmail.postfix
lrwxrwxrwx. 1 root root 41 Feb 14 15:29 mta-sendmailman -> /usr/share/man/man1/sendmail.postfix.1.gz
lrwxrwxrwx. 1 root root 33 Feb 16 16:02 pear -> /opt/remi/php73/root/usr/bin/pear
lrwxrwxrwx. 1 root root 38 Feb 16 16:02 phar -> /opt/remi/php73/root/usr/bin/phar.phar
lrwxrwxrwx. 1 root root 32 Feb 16 16:02 php -> /opt/remi/php73/root/usr/bin/php
lrwxrwxrwx. 1 root root 36 Feb 16 16:02 php-cgi -> /opt/remi/php73/root/usr/bin/php-cgi
```

PHP に関連するシムリンクの参照先を確認してみると

```
$ ls -l /usr/bin/ | grep php
lrwxrwxrwx. 1 root root        21 Feb 16 16:02 php -> /etc/alternatives/php
lrwxrwxrwx. 1 root root        32 Feb 15 12:18 php56 -> /opt/remi/php56/root/usr/bin/php
lrwxrwxrwx. 1 root root        36 Feb 15 12:18 php56-cgi -> /opt/remi/php56/root/usr/bin/php-cgi
lrwxrwxrwx. 1 root root        33 Feb 15 12:18 php56-pear -> /opt/remi/php56/root/usr/bin/pear
lrwxrwxrwx. 1 root root        38 Feb 15 12:18 php56-phar -> /opt/remi/php56/root/usr/bin/phar.phar
lrwxrwxrwx. 1 root root        32 Feb 15 12:18 php72 -> /opt/remi/php72/root/usr/bin/php
lrwxrwxrwx. 1 root root        36 Feb 15 12:18 php72-cgi -> /opt/remi/php72/root/usr/bin/php-cgi
lrwxrwxrwx. 1 root root        33 Feb 16 15:46 php72-pear -> /opt/remi/php72/root/usr/bin/pear
lrwxrwxrwx. 1 root root        38 Feb 15 12:18 php72-phar -> /opt/remi/php72/root/usr/bin/phar.phar
lrwxrwxrwx. 1 root root        32 Feb 15 12:32 php73 -> /opt/remi/php73/root/usr/bin/php
lrwxrwxrwx. 1 root root        36 Feb 15 12:32 php73-cgi -> /opt/remi/php73/root/usr/bin/php-cgi
lrwxrwxrwx. 1 root root        33 Feb 16 15:46 php73-pear -> /opt/remi/php73/root/usr/bin/pear
lrwxrwxrwx. 1 root root        38 Feb 15 12:32 php73-phar -> /opt/remi/php73/root/usr/bin/phar.phar
lrwxrwxrwx. 1 root root        25 Feb 16 16:02 php-cgi -> /etc/alternatives/php-cgi
```

/etc/alternarives のシムリンクからさらにシムリンクが生成されています。