PHPのバージョンを複数管理する(その1)

PHP5.4はまだ実用しないけど、traitなど新しい機能があるのでcliでは触っておきたい。
今からやろうとしてるFuelPHPは5.3以上でないと動作しなく、FuelPHPの実用も考えているので5.3も入れておきたい。
ということでrbenvならぬphpenvをいれてみることにする。
普段作業メモ残さないのがこちらのアカウントになりますので今回はブログ書きながらの作業となります。

1.Formuraある?

パッケージ管理はbrew使ってます。

$ brew search | grep php

単にbrew searchだけだと現在install可能なformuraが表示されるのだけれどPHPはないので
素直にbrew search phpすると

$ brew search php
josegonzalez/php/php53-pcntl		  josegonzalez/php/php54-http		       josegonzalez/php/php54-ssh2
etc

josegonzalez/phpのformuraを登録する必要があるみたいなのでbrew tapする

$ brew tap josegonzalez/php
Cloning into '/usr/local/Library/Taps/josegonzalez-php'...
remote: Counting objects: 1418, done.
remote: Compressing objects: 100% (675/675), done.
remote: Total 1418 (delta 733), reused 1303 (delta 638)
Receiving objects: 100% (1418/1418), 205.05 KiB | 95 KiB/s, done.
Resolving deltas: 100% (733/733), done.
Tapped 64 formura

Formuraに追加されたらしい

$ brew search php
php53-pspell	      php53-xhprof		php54-inclued		  php54-pcntl		    
etc

これでbrew install する準備が整った
※ついでだけどapacheもinstallしとく

$ brew tap Homebrew/dupes
$ brew install httpd
$ sudo httpd -k start

It works出たらおk

2.phpenv install

$ brew install phpenv
Error: phpenv is a head-only formula
Install with `brew install --HEAD phpenv`
'--HEADつけろと言われた
$ brew install --HEAD phpenv
==> Cloning https://github.com/CHH/phpenv.git
Cloning into '/Library/Caches/Homebrew/phpenv--git'...
remote: Counting objects: 17, done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 17 (delta 3), reused 14 (delta 1)
Unpacking objects: 100% (17/17), done.
==> /usr/local/Cellar/phpenv/HEAD/bin/phpenv-install.sh
==> Caveats
To finish installing phpenv:
 * Add ~/.phpenv/bin to your $PATH
 * Add "eval $(phpenv init -)" at the end of your ~/.bashrc
 * Restart your shell
==> Summary
/usr/local/Cellar/phpenv/HEAD: 5 files, 20K, built in 6 seconds

~/.phpenvができるので.bashrcとか.zshrcに環境変数の初期化とか初期化の設定をする

# rbenv
eval "$(rbenv init -)"
# phpenv
if [ -f ~/.phpenv/bin/phpenv ]; then
    export PATH=$PATH:~/.phpenv/bin
    eval "$(phpenv init -)"
fi

終わったら$ source ~/.zshrcで設定を適用

3.php-build install

$ brew install php-build
==> Downloading https://github.com/CHH/php-build/zipball/v0.8.0
######################################################################## 100.0%
==> Caveats
Tidy is enabled by default which will only work
on 10.7. Be sure to disable or patch Tidy for
earlier versions of OS X.
==> Summary
/usr/local/Cellar/php-build/0.8.0: 46 files, 196K, built in 4 seconds
$ php-build --definitions #ビルドできるバージョン
5.2.17
5.3.10
5.3.11
5.3.11RC1
5.3.11RC2
5.3.12
5.3.13
5.3.14
5.3.15
5.3.2
5.3.3
5.3.6
5.3.8
5.3.9
5.3.9RC3
5.3.9RC4
5.3snapshot
5.4.0
5.4.0RC1
5.4.0RC2
5.4.0RC3
5.4.0RC4
5.4.0RC5
5.4.0RC6
5.4.0RC7
5.4.0RC8
5.4.0alpha3
5.4.0beta1
5.4.0beta2
5.4.1
5.4.1RC1
5.4.1RC2
5.4.2
5.4.3
5.4.4
5.4.5
5.4snapshot

4.php-version install

$ brew install php-version
==> Downloading https://github.com/wilmoore/php-version/tarball/0.9.3
######################################################################## 100.0%
==> Caveats
Add the following script block to `$HOME/.bashrc`, `$HOME/.zshrc`, or your shell's equivalent configuration file.

Change `5.x.x` to the version of PHP you'd like your shell to default to or remove `php-version 5.x.x >/dev/null`
if you do not wish to have a default version of PHP loaded into your `$PATH`. The large comment block is optional:

########################################################################################
# php-version (activate default PHP version and autocompletion)
# PHP_HOME                      => should reflect location of compiled PHP versions
# PHPVERSION_DISABLE_COMPLETE=1 => to disable shell completion
########################################################################################
export PHP_VERSIONS=$(dirname $(brew --prefix php))
[ -f $(brew --prefix php-version)/php-version.sh ] &&
  source $(brew --prefix php-version)/php-version.sh && php-version 5.x.x >/dev/null
==> Summary
/usr/local/Cellar/php-version/0.9.3: 3 files, 20K, built in 3 seconds

php-versionコマンドを使用する際、$PHP_VERSIONの環境変数が設定されている必要があります。
なお、$PHP_VERSIONはインストールされるPHPディレクトリを指定します。
.zshrcもしくは.bashrcに以下のように書きます。

# PHP Install Directory
$PHP_VERSION=~/.phpenv/versions
# terminal起動時にphpの切り替えを行う
source $(brew --prefix php-version)/php-version.sh && php-version 5.3snapshot >/dev/null

何もしないとMacのデフォルトのPHPが使用されます。

5.PHPのビルド

いよいよphp-buildを使ってのPHPビルドになります。
参考サイトではapacheのmoduleだけ有効にしているようで、他のmoduleは?とか思ったけどこのまま進みます。
php-buildからphpをビルドする場合、configureは/usr/local/share/php-build/definitions/5.xのファイルにて設定します。

$ vi /usr/local/share/php-build/definitions/5.3snapshot
configure_option "--with-apxs2" "/usr/sbin/apxs"
install_package "http://snaps.php.net/php5.3-latest.tar.bz2"
install_pyrus
install_xdebug "2.2.0"

したらばLet's コンパイル

$ php-build 5.3snapshot ~/.phpenv/versions/5.3snapshot

コケた。/usr/libexec/apache2/libphp5.soのコピーでPermission Deniedとか出たのでsudoつけてみる。

$ sudo php-build 5.3snapshot ~/.phpenv/versions/5.3snapshot

今度は大丈夫でした。
以降、別バージョンのPHPをビルドすると、/usr/libexec/apache2下に生成されたlibphp5.soが上書きされてしまうので$PHP_VERSIONS下に退避させます。

sudo mv /usr/libexec/apache2/libphp5.so $PHP_VERSIONS/5.3snapshot

同じ要領で5.4snapshotもいれてしまいます。
とトライしたところ、以下のようなエラーが発生

/var/tmp/php-build/source/5.4snapshot/ext/curl/interface.c:2682:5: error: non-void function '_php_curl_setopt' should return a value [-Wreturn-type]
ZEND_FETCH_RESOURCE(sh, php_curlsh *, zvalue, -1, le_curl_share_handle_name, le_curl_share_handle);

バグっぽい。どこがってのはわからないけど、5.4.5はビルドできたのでまぁいっか。

6.php-versionで切り替えみる

今現在は5.3snapshotが適用されています。

$ php -v
PHP 5.3.16-dev (cli) (built: Aug 20 2012 06:49:39) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
    with Xdebug v2.2.0, Copyright (c) 2002-2012, by Derick Rethans

これをphp-versionで5.4.5に切り替えてみます。

$ php-version 5.4.5
SWITCHED PHP VERSION TO: 5.4.5
NEW PHP ROOT DIRECTORY : /Users/sasakiyasuyuki/.phpenv/versions/5.4.5
$ php -v
PHP 5.4.5 (cli) (built: Aug 21 2012 23:22:25) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
    with Xdebug v2.2.0, Copyright (c) 2002-2012, by Derick Rethans

おおおーーー。できた。

本記事はいったんここで終わりにし、次回、Apacheモジュールの切り替えと、Pyrusでphpunitの導入を実際に試してみます。

補足 デフォルトのconfigure option

configure-optionはapxs2しか指定しませんでしたが、configure-optionのデフォルトはこちらになります。

$ vi /usr/local/Cellar/php-build/0.8.0/share/php-build/default_configure_options
--without-pear \
--with-gd
--enable-sockets
--with-jpeg-dir=/usr
--with-png-dir=/usr
--enable-exif
--enable-zip
--with-zlib
--with-zlib-dir=/usr
--with-kerberos
--with-openssl
--with-mcrypt=/usr
--enable-soap
--enable-xmlreader
--with-xsl
--enable-ftp
--enable-cgi
--with-curl=/usr
--with-tidy
--with-xmlrpc
--enable-sysvsem
--enable-sysvshm
--enable-shmop
--with-mysql=mysqlnd
--with-mysqli=mysqlnd
--with-pdo-mysql=mysqlnd
--with-pdo-sqlite
--enable-pcntl
--with-readline
--enable-mbstring
--disable-debug

バージョンごとに設定するのが面倒だという人はこちらに書くのもいいかもですね。