phpenv+php-build環境によるphpバージョン管理~Mac（Yosemite）編~


##はじめに
皆さんこんにちは。
`Mac`で`php`の開発をよくしますが、`php`のバージョン管理`phpenv`を使ってないなーと思ったので導入してみました。
導入から`phpenv`の基本的な使い方をちょっと紹介します。

##phpenv&php-buildの導入
`phpenv`とは、一つのサーバー内にて複数の`php`のバージョンを管理するツールです。`ruby`でいうところの`rbenv`ですね。そちらを使っている人であればわかると思います。
複数のプロジェクトの掛け持ちやバージョンによる挙動の確認をしたいときなど、phpを複数バージョンで使用しなければならない時に使用します。
`phpenv`は2つ公開されていて、php-buildを別途使うものか使わないものかで分類されているようです。
今回はphp-buildを利用する環境を作ってみたいと思います。

###phpenvのインストール
ではまず`phpenv`をインストールします。ここに関してはログが消えてしまい具体的なコマンド忘れました笑。基本的に他の記事参考にすれば特に問題ありませんでした。お手数ですが他の記事を探して参考にして頂ければと思います。今回は以下の様なサイトを主に参考にさせて頂きました。

[MavericksにphpenvでPHP5.5を入れる]
(http://itexp.hateblo.jp/entry/install-php55-with-phpenv-on-mavericks)
[phpenv + php-buildでphpのバージョン管理](http://kimikimi714.hatenablog.com/entry/2014/03/06/phpenv_%2B_php-build%E3%81%A7php%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86)
[CentOSにrbenvとphpenvをシステムワイドにインストール](http://qiita.com/ktaro/items/513ac42f1f4a2b30ffee)

インストール後は`phpenv`のパスを通します。
**`rbenv`を導入していない場合**は`.bash_profile`に以下の項目を追記。

```bash:bash
export PATH="$HOME/.phpenv/bin:$PATH"
eval "$(phpenv init -)”
```

もし **`rbenv`をすでに導入済の場合は、`rbenv`のパスより後に`phpenv`のパスを記述する**ようにしてください。
コード例としてはこんな感じ。

```bash:.bash_profile
#rbenv
export RBENV_ROOT="/usr/local/rbenv"
PATH="$RBENV_ROOT/bin:$PATH"

#phpenv
export PHPENV_ROOT="/usr/local/phpenv"
PATH="$PATH:$PHPENV_ROOT/bin"

export PATH
eval "$(rbenv init -)"
eval "$(phpenv init -)"
```

###php-buildのインストール
`php-build`は`brew`でインストールできるので下記のコマンドを実行。

```bash:bash
$ brew install php-build
```

ひとまずこれで`phpenv`と`php-build`の準備はOKです。

##phpのバージョン変更
導入も済んだのでそれでは実際に使ってみましょう。
まずインストール可能な`php`のバージョンを確認してみましょう。以下のコマンドを実行するとこのような出力となります。

```bash:bash
$ phpenv install -l
```

```bash:出力結果
$ phpenv install -l
usage: phpenv install VERSION

Available versions:
 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.6.0beta2
 5.6.0beta3
 5.6.0beta4
 5.6.1
 5.6.2
 5.6.3
 5.6snapshot
 master
```

上記のようにインストール可能な`php`のバージョンが確認できます。※バージョンが多いので一部省略してます。
対象バージョンのインストールは下記のコマンドを実行するとできます。

```bash:bash
$ phpenv install 対象バージョン
```

##phpのインストール失敗時の対処法
上記の手順で実際には`php`のインストールが可能ですが、インストールにあたって準備をしていないと失敗することがあります。依存パッケージがいくつかあるのでインストールするなどの準備をしておく必要があります。私は5.6.2をインストールしようと試みましたが見事にハマりました...。
そこで、失敗した場合のエラー文と対処法について少し紹介します。

### 主な失敗例
ログが消えてはっきりしませんが、自分の場合は`bison`、`re2c`、`jpeglib.h`、`mcrypt.h`、`autoconf`、`automake`あたりでした。多いですね苦笑
１つずつ対処法を紹介します。

**bison**
`bison`のエラーはこんな感じでした。

```bash:bisonエラー文
configure: WARNING: bison versions supported for regeneration of the Zend/PHP ~~なんちゃら
```

現在の`bison`のバージョンがサポートされていないようです。なのでアップデートしてみました。
が...。

```bash:bash
$ brew info bison
bison: stable 3.0.2 (bottled)
```

最新バージョンが対応していませんでした。 *なぜなのか。*

調べると2.7が対応しているとのことでしたのでバージョンダウンさせます。そこで必要になってくるのが、brewのversionsコマンド。実はこのコマンドは現行のbrewではすでに廃止になっていて使えません。なので別途versionsコマンドを使えるようにする処理をしてから行いました。
※他の代替コマンドで出来るようでしたが今回は参考記事にしたがってやることにしました。代替コマンドは後ほど試したいと思います。

versionsコマンドが使えるようになったら`bison`の過去のバージョンを確認してみましょう。

```bash:bash
$ brew versions bison
Warning: brew-versions is unsupported and will be removed soon.
You should use the homebrew-versions tap instead:
  https://github.com/Homebrew/homebrew-versions

3.0.2    git checkout 3868896 /usr/local/Library/Formula/bison.rb
3.0.1    git checkout 4715b3c /usr/local/Library/Formula/bison.rb
3.0      git checkout b744b43 /usr/local/Library/Formula/bison.rb
2.7.1    git checkout 804bcf6 /usr/local/Library/Formula/bison.rb
2.7      git checkout adf87c6 /usr/local/Library/Formula/bison.rb
```

ここでもversionsコマンドはサポートしてませんと警告されてますがとりあえず無視します（ぇ
では2.7をインストールします。下記のコマンドを実行します。

```bash:bash
$ cd `brew —prefix`
$ pwd
/usr/local
$ git checkout adf87c6 /usr/local/Library/Formula/bison.rb
$ brew install bison
```

これでbsionのエラーが消えるかと思います。

###re2c
`re2c`のエラーはこんな感じでした。

```bash:re2cエラー文
configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.
```

`re2c`は字句解析器を書くためのツールのようです。
こちらは`brew`でインストールすれば大丈夫ですので以下のコマンドを実行

```bash:bash
$ brew install re2c
```

###jpeglib.h
`jpeglib.h`のエラー文はこんな感じでした。

```bash:jpeglib.hのエラー文
configure: error: jpeglib.h not found.
```

これは時間かかりました...。調べましたが、特に問題なければ以下のコマンドを実行して`brew`でインストールすれば大丈夫のようです。

```bash:bash
$ brew install libjpegn
```

自分の場合上記コマンドを実行してもすでにインストール済みだと怒られます。
最終的には、`jpeg`を`brew uninstall`してからjpegの再インストールで乗り越えました。
ご参考程度に。

###mcrypt.h
もともと、上記`bison`、`re2c`、`jpeglib.h`のエラーしか出ていませんでしたが、新たにこのエラーが出現しました。
`mcrypt.h`のエラー文はこんな感じでした。

```bash:mcrypt.hのエラー文
configure: error: mcrypt.h not found. Please reinstall libmcrypt.
```

対処方法としては`brew`にて再インストールで大丈夫です。

```bash:bash
$ brew reinstall libmcrypt
```

###中間報告
上記対処でエラーが全て消えました。今度こそ...！と、意気込んで`php`のインストールをしましたがとんでもない結果に。

```bash:出力結果
$ phpenv install 5.6.2
[Info]: Loaded apc Plugin.
[Info]: Loaded composer Plugin.
[Info]: Loaded pyrus Plugin.
[Info]: Loaded xdebug Plugin.
[Info]: Loaded xhprof Plugin.
[Info]: php.ini-production gets used as php.ini
[Info]: Building 5.6.2 into /Users/username/.phpenv/versions/5.6.2
[Skipping]: Already downloaded and extracted http://php.net/distributions/php-5.6.2.tar.bz2
[Preparing]: /var/tmp/php-build/source/5.6.2
[Compiling]: /var/tmp/php-build/source/5.6.2
[Pyrus]: Downloading from http://pear2.php.net/pyrus.phar
[Pyrus]: Installing executable in /Users/username/.phpenv/versions/5.6.2/bin/pyrus
[XDebug]: Downloading http://xdebug.org/files/xdebug-2.2.6.tgz
[XDebug]: Compiling in /var/tmp/php-build/source/xdebug-2.2.6

-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
                       ^
/usr/include/math.h:718:12: note: 'finite' has been explicitly marked deprecated here
extern int finite(double) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_9, __IPHONE_NA, __IPHONE_NA);
           ^
1 warning generated.
/var/tmp/php-build/source/5.6.2/Zend/zend_string.c:65:28: warning: assigning to 'char *' from 'const char *' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers]
        CG(interned_empty_string) = zend_new_interned_string_int("", sizeof(""), 0 TSRMLS_CC);
                                  ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
PEAR package PHP_Archive not installed: generated phar will require PHP's phar extension be enabled.
-----------------------------------------

The full Log is available at '/tmp/php-build.5.6.2.20141226031942.log'.
[Warn]: Aborting build.
```

何だこのエラーは...増えた...。
これの対処法について先に紹介します。

###エラー原因を特定する
この原因の特定が難しかったので調べると、`~/.phpenv/plugins/php-build/share/php-build/plugins.d/xdebug.sh`の68~75行目の`/dev/null`が悪さをしているみたいでした。
下記のような項目です。

```bash:~/.phpenv/plugins/php-build/share/php-build/plugins.d/xdebug.sh
{
    $PREFIX/bin/phpize > /dev/null
    "$(pwd)/configure" --enable-xdebug \
    --with-php-config=$PREFIX/bin/php-config > /dev/null

    make > /dev/null
    make install > /dev/null
} >&4 2>&1
```

ログが全部`/dev/null`に入ってしまっているのでこんなふうになってたのかと思います。
なので`/dev/null`を削除し以下のように修正します。

```bash:~/.phpenv/plugins/php-build/share/php-build/plugins.d/xdebug.sh
{   
    $PREFIX/bin/phpize
    "$(pwd)/configure" --enable-xdebug \
    --with-php-config=$PREFIX/bin/php-config

    make
    make install
} >&4 2>&1
```


これで再度インストールしてみましょう。
すると先ほどのエラー文が変化し以下のようになっていました。

```bash:bash
$ phpenv install 5.6.2
[Info]: Loaded apc Plugin.
[Info]: Loaded composer Plugin.
[Info]: Loaded pyrus Plugin.
[Info]: Loaded xdebug Plugin.
[Info]: Loaded xhprof Plugin.
[Info]: php.ini-production gets used as php.ini
[Info]: Building 5.6.2 into /Users/username/.phpenv/versions/5.6.2
[Skipping]: Already downloaded and extracted http://php.net/distributions/php-5.6.2.tar.bz2
[Preparing]: /var/tmp/php-build/source/5.6.2
[Compiling]: /var/tmp/php-build/source/5.6.2
[Pyrus]: Downloading from http://pear2.php.net/pyrus.phar
[Pyrus]: Installing executable in /Users/username/.phpenv/versions/5.6.2/bin/pyrus
[XDebug]: Downloading http://xdebug.org/files/xdebug-2.2.6.tgz
[XDebug]: Compiling in /var/tmp/php-build/source/xdebug-2.2.6

-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
                                  ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
PEAR package PHP_Archive not installed: generated phar will require PHP's phar extension be enabled.
Configuring for:
PHP Api Version:         20131106
Zend Module Api No:      20131226
Zend Extension Api No:   220131226
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.
-----------------------------------------

The full Log is available at '/tmp/php-build.5.6.2.20141226173041.log'.
[Warn]: Aborting build.
```

この文を見ると途中に、
`Cannot find autoconf.`と書いてあるのがわかりますね。こいつが原因でした。

###autoconf、automake
`autoconf`はビルドツールであり`OS X Lion`あたりから手動でインストールしなければならなくなったようです。
ついでに`automake`というビルドツールも参考記事に載っていたのでインストールしておきました。
これらは`brew`でインストール可能です。以下のコマンドを実行しました。

```bash:bash
$ brew install autoconf
$ brew install automake
```

これで完了です。
この後ついに対象バージョンのインストールが出来ました！

##phpenvの基本操作
さて、実際に対象バージョンの`php`をインストールできたらあとは設定をするだけです。

まずは以下のコマンドを実行しましょう。
現在の`php`のバージョン確認とインストール済み`php`バージョンの確認コマンドです。

```bash:bash
$ phpenv versions
* system (set by /Users/username/.phpenv/version)
  5.6.2
```

「*」がついてるバージョンがが適用されているということです。
`sysytem`とはもともと`Mac`に入っている`php`バージョンのことを指しています。デフォルトだとこのような状態ですね。
念のため`php`のバージョンをチェックしてみます。

```bash:bash
$ php -v
PHP 5.5.14 (cli) (built: Sep  9 2014 19:09:25) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
```

現行のバージョンは5.5.14でした。
ではインストールしたバージョンを指定してみましょう。渡しの場合は5.6.2です。コマンドは以下の通り

```bash:bash
$ phpenv global 5.6.2
$ phpenv rehash
```

これでもう一度確認してみます。

```bash:bash
$ phpenv versions
  system
* 5.6.2 (set by /Users/username/.phpenv/version)
```

```bash:bash
$ php -v
PHP 5.6.2 (cli) (built: Dec 26 2014 17:55:30) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.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.6, Copyright (c) 2002-2014, by Derick Rethans
```

バージョンが変更されているのがわかります。

##最後に
エラー対処に時間がかかったところもありますが、以下に紹介します参考文献に例が載っていたので対処しやすかったです。
参考にさせていただいた記事を紹介させていただきます。ありがとうございました！

[MavericksにphpenvでPHP5.5を入れる]
(http://itexp.hateblo.jp/entry/install-php55-with-phpenv-on-mavericks)
[phpenv + php-buildでphpのバージョン管理](http://kimikimi714.hatenablog.com/entry/2014/03/06/phpenv_%2B_php-build%E3%81%A7php%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86)
[CentOSにrbenvとphpenvをシステムワイドにインストール](http://qiita.com/ktaro/items/513ac42f1f4a2b30ffee)
[Homebrewでphp-build及びphpenvインストール後に5.5系をインストールするための手順](http://qiita.com/tebonz/items/82ad7e57066650d43b28)
[複数バージョンの PHP を管理できる phpenv のインストール手順](http://www.serendip.ws/archives/6275)
[macにphpenv,php-build,apacheで開発環境を構築したのでメモ](http://box406.hatenablog.com/entry/2013/04/01/232212)
[phpenv を使って AWS EC2 に php をインストールしようとしてエラーが出た時の対処法](http://mj-wave.com/post-926/)
[ubuntuにphp-buildでphp5.5を入れるためにシェルスクリプトと格闘した記録](http://hirobanex.net/article/2013/09/1379231000)
[Xcode4.3, Mac OS X Lionの環境でhomebrewからautoconf、automakeをインストールする](http://yoppi.hatenablog.com/entry/20120414/setting_build_tools_on_mac_osx_lion)
[phpenv + php-buildでPHPを複数バージョン利用する方法](http://liginc.co.jp/web/programming/php/126863)