phpenv を利用して、複数のバージョンの PHP を切り替えて使えるようにする手順を紹介します。phpenv についてはウェブに多くの情報が見つかりますが、ここでは、anyenv の配下に phpenv/phpenv をインストールして、そのプラグインとして CHH/php-build を利用する方法で PHP の環境を構築します。
anyenv の導入
はじめに、anyenv をインストールします。anyenv は、rbenv や pyenv など、phpenv を含む *env 系のコマンドを一元管理できるようにしたものです。作者の方による紹介記事と GitHub のリポジトリは、それぞれ以下にあります。
GitHub の説明どおりにインストールします。
$ git clone https://github.com/riywo/anyenv ~/.anyenv $ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile $ echo 'eval "$(anyenv init -)"' >> ~/.bash_profile $ exec $SHELL -l
以下のように anyenv コマンドが認識されます。
$ which anyenv ~/.anyenv/bin/anyenv
phpenv の導入
次に、phpenv をインストールします。anyenv を用いて以下のようにインストールできます。
$ anyenv install phpenv $ exec $SHELL -l
これで、phpenv コマンドも認識されるようになります。anyenv を利用して *env をインストールすると、以下のように ~/.anyenv/envs ディレクトリに各 *env 環境が作成されます。
$ which phpenv ~/.anyenv/envs/phpenv/bin/phpenv
phpenv には CHH/phpenv と phpenv/phpenv の二種類があり、anyenv でインストールされるのは後者の phpenv/phpenv の方です*1。それぞれの GitHub リポジトリは以下になります。phpenv の情報を調べるときには、どちらの phpenv について書かれている情報かに注意してください。
php-build の導入
phpenv/phpenv は、rbenv に依存していない点や PHP をビルドしてインストールできる点など、CHH/phpenv に比べて有利な点があるようですが*2、私の環境では install コマンドが上手く動きませんでした。そこで、install コマンドの機能のみ CHH/php-build を導入して実現することにします。CHH/php-build のリポジトリは以下になります。
CHH/php-build を phpenv/phpenv のプラグインとして導入します。以下のように phpenv の plugins ディレクトリに php-build を置くことで、phpenv のプラグインとして利用できるようになります。
$ cd ~/.anyenv/envs/phpenv $ git clone https://github.com/CHH/php-build.git plugins/php-build
phpenv が提供している install コマンドを削除することで、php-build 側の install コマンドが使われるようにします*3。削除ではなくファイル名を変更する方法でも問題ありません。
$ rm libexec/phpenv-install
これで、php-build が提供する install コマンドを利用できるようになりました。バージョンを指定せずに phpenv install と入力すると、インストール可能なバージョンの一覧が表示されます。
$ phpenv install phpenv v0.0.4-dev usage: phpenv install VERSION phpenv install /path/to/definition Available versions: 5.2.17 5.3.10 5.3.11 ...
表示される一覧は、以下のディレクトリに存在するものです。これは PHP のリリースに応じて php-build のリポジトリが更新されています。したがって、新しい PHP をインストールするには、git pull して php-build のリモートリポジトリの変更を取り込む必要があります。
$ ls -1 ~/.anyenv/envs/phpenv/plugins/php-build/share/php-build/definitions | head 5.2.17 5.3.10 5.3.11 5.3.12 5.3.13 5.3.14 5.3.15 5.3.16 5.3.17 5.3.18
PHP のインストールと切り替え
ここまでの作業で導入された phpenv を用いて PHP のインストールと切り替えを試してみます。たとえば、現時点での 5.5 系の最新である 5.5.17 をインストールするには、次のようにコマンドを実行します。指定したバージョンの PHP がダウンロードされ、ビルドされます。ソースコードからビルドしてインストールすることになるので、ビルドに必要な環境はあらかじめ導入されている必要があります。
$ phpenv install 5.5.17 ...
ビルドに成功すると、phpenv verions コマンドで以下のように確認できます。インストール済みの PHP の一覧が表示されます。行頭のアスタリスクは、現在の PHP のバージョンを示します。system は、phpenv で管理されていない、このシステムのデフォルトの PHP を表します。
$ phpenv versions phpenv v0.0.4-dev * system (set by /home/y-uti/.anyenv/envs/phpenv/version) 5.5.17
PHP のバージョンを切り替えるには、phpenv global コマンドを実行します。
$ phpenv global 5.5.17 phpenv v0.0.4-dev 5.5.17
これで、php のバージョンが 5.5.17 になります。
$ php -v PHP 5.5.17 (cli) (built: Oct 13 2014 17:34:29) Copyright (c) 1997-2014 The PHP Group Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2014, by Zend Technologies with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans
デフォルトの PHP に戻すにはバージョンとして system を指定します。
$ phpenv global system phpenv v0.0.4-dev system
CentOS 7 の yum でインストールされる 5.4.16 に切り替わっていることを確認できます。
$ php -v PHP 5.4.16 (cli) (built: Sep 30 2014 09:44:39) Copyright (c) 1997-2013 The PHP Group Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
ビルドされた PHP の実体は、たとえば 5.5.17 であれば下記のディレクトリにあります。php.ini ファイルなどもこのディレクトリの配下に置かれており、バージョンごとに編集できます。
~/.anyenv/envs/phpenv/versions/5.5.17
PHP のビルドオプション等の構成を変更するには、下記のディレクトリ配下にあるファイルを編集します。
~/.anyenv/envs/phpenv/plugins/php-build/share/php-build
具体的な編集方法は、詳細に書きはじめると長くなってしまうので省略します。以下の記事などが参考になると思います。
Apache module のインストール
phpenv install を実行したときに、Apache のモジュールもインストールされるように設定します。まず、次のようにファイルを編集して、PHP のビルドオプションに --with-apxs2 を追加します。
$ vi ~/.anyenv/envs/phpenv/plugins/php-build/share/php-build/default_configure_options ... --with-apxs2=/usr/bin/apxs2
これで libphp5.so が作られるようになりますが、現在の php-build には問題があり、この状態でビルドすると libphp5.so を /etc/httpd/modules に出力してしまいます*4。この問題を修正するパッチが以下の記事で公開されています。
このパッチを適用して php-build を修正します。
$ cd ~/.anyenv/envs/phpenv/plugins/php-build/bin $ curl https://gist.githubusercontent.com/tkuchiki/10112836/raw/php-build.patch | patch -u php-build -
phpenv install すると、たとえば 5.5.17 であれば以下の場所に libphp5.so が出力されるようになります。
~/.anyenv/envs/phpenv/versions/5.5.17/libexec/libphp5.so
phpenv global で環境を切り替えると、指定したバージョンの libphp5.so へのシンボリックリンクが以下の場所に作成されます。これを LoadModule で指定することで、Apache 側の設定を変更せずに PHP のバージョン切り替えを反映させられます。
$ LANG=C ls -l ~/.anyenv/envs/phpenv/lib/libphp5.so | cut -f9- -d' ' /home/y-uti/.anyenv/envs/phpenv/lib/libphp5.so -> /home/y-uti/.anyenv/envs/phpenv/versions/5.5.17/libexec/libphp5.so*
ただし、PHP を yum でインストールしている環境では、phpenv global system でデフォルトのバージョンに切り替えたときに、/etc/httpd/modules/libphp5.so へのシンボリックリンクを作成してくれない問題があります*5。この問題は phpenv-global を修正して解決できます。
@@ -44,6 +44,9 @@ # Link Apache apxs lib APXS="" +if [ "${PHPENV_VERSION}" == "system" ]; then + APXS="$(which apxs 2>/dev/null)" +fi php-config --configure-options 2>/dev/null | grep -q apxs && \ APXS="$(php-config --configure-options| sed 's/.*=\(.*apxs[^ ]*\) .*/\1/')"
Gist にパッチを公開しましたので、以下のようにして適用できます。
$ cd ~/.anyenv/envs/phpenv/libexec $ curl https://gist.githubusercontent.com/y-uti/69e0b17f916fb5a25df4/raw/191dbfae6428ca55e311fb094991c4aa9295ab36/phpenv-global.patch | patch -
anyenv-update プラグインのインストール
anyenv, phpenv, php-build の更新 (git pull) を一括して実行できるように、anyenv-update プラグインを導入します。作者の方による紹介記事と GitHub のリポジトリは、それぞれ以下にあります。
GitHub のリポジトリを clone してインストールします。
git clone https://github.com/znz/anyenv-update.git ~/.anyenv/plugins/anyenv-update
このプラグインを利用すると、次のようにして anyenv 配下の環境を一括して更新できます。
$ anyenv update Updating 'anyenv'... Already up-to-date. Updating 'anyenv-update'... Already up-to-date. Updating 'phpenv'... Already up-to-date. Updating 'php-build'... Already up-to-date.
(2014/10/18 追記)
この記事の手順でソースコードの修正やパッチの適用を行うと、git pull に失敗することがあります。これは、修正が commit されていないことが原因です。修正を commit すると、git pull の際にマージが行われて正常に環境を更新できます*6。
*1:phpenv/phpenv の dev branch を取得するようになっています。
*2:CHH/phpenv では、git clone した後に bin/phpenv-install.sh を実行し、rbenv のコードを取得して phpenv 用にコードの一部を変更するという導入方式になります。また、CHH/phpenv は PHP の切り替えのみに対応しており、PHP のインストールには別途 CHH/php-build を導入する必要があります。
*3:phpenv 本体のコマンド群は libexec サブディレクトリにあります。phpenv が設定する PATH の順番として、plugins 配下よりも libexec が優先されるようになっているため、同名のコマンドが存在する場合は libexec 側が優先されます。詳細は libexec/phpenv で bin_path を設定している箇所を参照してください。
*4:普通は一般ユーザの書き込み権限はないはずなので、sudo しない限り実際に上書きされてしまうことはないと思いますが。
*5:phpenv global では、php-config --configure-options で apxs の指定の有無を調べているのですが、yum でインストールされた PHP では --with-apxs2 オプションが指定されていないため、シンボリックリンクが更新されません。
*6:もちろん、修正箇所が conflict してしまった場合には解消する必要がありますが、私が今まで使っているなかでは、conflict の解消が必要になったことはありません。