第38回PHP勉強会でも紹介しましたが、私はPHP5.0.0〜PHP5.2.8までの全バージョンのPHPバイナリを持っています。これはPHPのバージョン間の差異やバグを確認したいときなどに便利です。(参考:「第38回PHP勉強会に参加してきました」)
このような環境を作る方法について紹介します。基本的には各バージョンのPHPをコンパイルするだけですが、コンパイルが通らない場合があるのでその回避方法と、かんたんインストールスクリプトを用意したのでそれを紹介します。また、全てのバージョンのPHPを順に実行するコマンドphpallについても紹介します。
PHP5をgcc4環境でコンパイルする
実は、PHP 5.0.0-5.0.3はgcc4 でコンパイルできないという問題点があります。gcc4でコンパイルするためには、http://bugs.php.net/bug.php?id=32150 の通り、Zend/zend_modules.h を修正する必要があります。
こんなときgcc3でコンパイルするのも一つの手ですが、MacOSX10.4や10.5ではgcc3が提供されていません。今後このような環境が増えてくるのではないでしょうか。
また、PHP 5.2.0-5.2.3は./configureの途中で下記のように怒られてしまいます。
configure: error: installation or configuration problem: C++ compiler cannot create executables.
原因は追いかけていませんが、autoconfでconfigureスクリプトを作り直すと問題なくバイナリのビルドまで通ります。
MacOSX上でのコンパイル
MacOSX上でコンパイルするためには他にも工夫が必要です。
まず、MacOSX環境でPHP 5.0.0-5.0.5をコンパイルするためにはCFLAGS='-fnested-functions'の指定が必要です。というのも、configureスクリプト中でコンパイルしているCプログラムがXcodeのgccではコンパイルできないため、configureで間違った判定をしてしまうのです。(参考:http://developer.apple.com/jp/technotes/tn2006/tn2161.html)
また、PHP 5.0.0-5.0.5では鬼車同梱のlibxml2とLeopard標準のlibxml2がコンフリクトしてしまう問題があります。これはどちらも使わずに最新のlibxml2を使えば問題なく動くようですので、私はHomebrewのlibxml2を利用することにしました。
らくらくコンパイル&インストール
上記の手順を全部含んだシェルスクリプトを作りました。まず作業ディレクトリにphpのパッケージを必要なだけダウンロードして、PHPを片っ端からインストールするシェルスクリプト(install-all-php.sh)を実行してください。パッケージを展開してコンパイルして、出来たバイナリを$HOME/binにphp-5.?.?という名前でインストールします。
事前にflexやbisonやlibxml2やlibiconvなど必須パッケージのインストールをお忘れなく。
$ ls php-*.tar.* php-5.0.0.tar.gz php-5.1.0.tar.gz php-5.1.6.tar.bz2 php-5.2.5.tar.bz2 php-5.0.1.tar.gz php-5.1.1.tar.gz php-5.2.0.tar.bz2 php-5.2.6.tar.bz2 php-5.0.2.tar.gz php-5.1.2.tar.gz php-5.2.1.tar.bz2 php-5.2.7.tar.bz2 php-5.0.3.tar.gz php-5.1.3.tar.gz php-5.2.2.tar.bz2 php-5.2.8.tar.bz2 php-5.0.4.tar.gz php-5.1.4.tar.bz2 php-5.2.3.tar.bz2 php-5.0.5.tar.gz php-5.1.5.tar.bz2 php-5.2.4.tar.bz2 $ wget http://github.com/hnw/phpall/raw/master/install-all-php.sh $ sh ./install-all-php.sh
下記の手順でも同じことですが、それぞれ時間がかかるのでシェルスクリプト一発の方がおすすめです。
$ for i in php-*.tar.gz ; do tar xvzf $i; done ; for i in php-*.tar.bz2 ; do tar xvjf $i; done $ for i in php-5.0.[0123] ; do cd $i ; perl -i.bak -pe 's|#include "zend.h"|#include "zend.h"\n#include "zend_compile.h"|' Zend/zend_modules.h; cd ..; done #MacOSXのみ $ for i in php-5.0.? ; do cd $i ; CFLAGS='-fnested-functions' ./configure --with-libxml-dir=/opt/local -with-iconv=/opt/local --enable-mbstring --disable-cgi ; make ; cd .. ; done #MacOSX以外 $ for i in php-5.0.? ; do cd $i ; ./configure --enable-mbstring --disable-cgi ; make ; cd .. ; done $ for i in php-5.[12].? ; do cd $i ; ./configure --enable-mbstring --disable-cgi || ( autoconf && ./configure --enable-mbstring --disable-cgi ) ; make ; cd .. ; done $ for i in php-5.?.? ; do install $i/sapi/cli/php $HOME/bin/$i; done
phpallコマンド
上記のphpたちを簡単にテストするためのシェルスクリプト、phpallを作りました。$HOME/bin(またはphpをインストールしたディレクトリ)にインストールして使います。
phpallコマンドはPHPのコードを引数として受け取り、それを実行します。実行結果が標準出力に出力がない場合はコード全体をvar_dump()で囲んで再実行します。また、引数がファイルだった場合はPHPとして実行します。
$ phpall '"0x1"=="1e0"' php-5.0.0: bool(true) php-5.0.1: bool(true) php-5.0.2: bool(true) php-5.0.3: bool(false) php-5.0.4: bool(false) php-5.0.5: bool(false) php-5.1.0: bool(false) php-5.1.1: bool(false) php-5.1.2: bool(false) php-5.1.3: bool(false) php-5.1.4: bool(false) php-5.1.5: bool(false) php-5.1.6: bool(false) php-5.2.0: bool(false) php-5.2.1: bool(true) php-5.2.2: bool(true) php-5.2.3: bool(true) php-5.2.4: bool(true) php-5.2.5: bool(true) php-5.2.6: bool(true) php-5.2.7: bool(true) php-5.2.8: bool(true)
これさえあれば簡単にPHPの実験ができますね!
注意点ですが、PHPの複文(foo(123);bar("str");など)を実行して標準出力が空だった場合も全体をvar_dump()で囲んで再実行してしまい、結果として全バージョンでエラーになってしまいます。これは現時点でのphpallのバグです。複文を実行したい場合は明示的にprint_r()やvar_dump()してください。