PHP
MacOSX
phpenv

phpenvが動かないのなら作りなおせばいいじゃない

More than 5 years have passed since last update.


長いのでまとめ


  • PHP初心者(自分)がバージョン管理ツールを探していた

  • OSX Mavericks上のPHPのバージョン管理をphpenv & php-buildでやってみよう

  • php-buildでインストールしたバージョンに切り替えてphp -vしたところ、何故かrbenvエラー

  • rbenvの仕組みを利用すると自分でもphpenv作れそう

  • ✌(・ω・)


インストール道中記

PHPでrbenv的なものを探して見たところ、phpenv & php-buildがよさ気っぽいと知る。

phpenv + php-buildでphpのバージョン管理 - わすれっぽいきみえ

HomebrewでPHP環境構築してマルチバージョン管理 | iii ThreeTreesLight

$ brew tap homebrew/dupes

$ brew tap jisegonzalez/homebrew-php
$ brew update
$ brew upgrade

$ brew install —HEAD phpenv
$ brew install —HEAD php-build

PHP周りの便利ツール探してるとCHH氏とjisegonzalez氏によく行き着くので抑えておくと良いのかな。

続けてphpenvの設定。

# phpenvの設定

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

このままphp-build ${VERSION} path/したいところだが、build errorにならぬよう以下のパッケージをインストール。


  • wget

  • re2c (字句解析)

  • mcrypt

試しに2バージョン入れて切り替えるとこまで。

$ php-build 5.4.25 ~/.phpenv/versions/5.4.25

$ php-build 5.5.9 ~/.phpenv/versions/5.5.9

$ phpenv versions
* system (set by /Users/laprasDrum/.phpenv/version)
5.4.25
5.5.9
$ php -v
PHP 5.5.12 (cli) (built: May 9 2014 22:22:54)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies

$ phpenv global 5.4.25
$ phpenv rehash
$ phpenv versions
system
* 5.4.25 (set by /Users/laprasDrum/.phpenv/version)
5.5.9

$ php -v
rbenv: gem: command not found
/usr/local/Cellar/rbenv-gemset/0.5.6/etc/rbenv.d/exec/gemset.bash: line 33: : command not found

えっ…


.bashrc/.zshrcの確認

ググったところ、PATHの設定上ローカルのrbenvが先にロードされるようにとのこと。

phpenvで複数の PHP 環境を管理する


rbenv をインストールしている場合

先にも書きましたが, phpenv は rbenv を利用した作りになっています.

その関係もあって, PATH の設定は rbenv が phpenv よりも先になっていないと, 正常に動作しません.

~/.bashrc や ~/.zshrc の設定は, 例えば以下のようにする必要があるので注意が必要です.


# rbenv & phpenv

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


再インストール

念のため、先ほどインストールしたPHPを削除。

念のため。

$ rm -rf ~/.phpenv/versions/*

$ phpenv global system
$ phpenv rehash

$ phpenv versions
* system (set by /Users/laprasDrum/.phpenv/version)
$ php -v
PHP 5.5.12 (cli) (built: May 9 2014 22:22:54)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies

再度インストール。

$ php-build 5.4.25 ~/.phpenv/versions/5.4.25

$ php-build 5.5.9 ~/.phpenv/versions/5.5.9

$ phpenv versions
* system (set by /Users/laprasDrum/.phpenv/version)
5.4.25
5.5.9

$ phpenv global 5.4.25
$ phpenv rehash
$ phpenv versions
system
* 5.4.25 (set by /Users/laprasDrum/.phpenv/version)
5.5.9

$ php -v
rbenv: gem: command not found
/usr/local/Cellar/rbenv-gemset/0.5.6/etc/rbenv.d/exec/gemset.bash: line 33: : command not found

……


phpenv作りなおすか

これ、phpenvがrbenvを中途半端にラップしてて実装ミスあるんじゃないの…と思い始める。

ここでrbenv自体どのようにバージョン管理しているのか気になって調べてみることに。

rbenvの切り替えの仕組み…と、他言語での実験 - すぎゃーんメモ


rbenvを使用する設定をした状態でrubyコマンドを叩くと、




  1. ${RBENV_ROOT}/shims/rubyが呼ばれ、その中で


  2. rbenv-execが呼ばれ、その中では


  3. rbenv-whichで実行すべきrubyを探すが、それは中で


  4. rbenv-version-nameで実行すべきrubyのバージョンを特定し、そいつが中で


  5. rbenv-version-file.rbenv-versionファイルがあるかどうか調べる


という流れになる。.rbenv-versionファイルが見つかれば、




  1. rbenv-version-fileがそのファイルパスを返し、


  2. rbenv-version-nameがそこから読み取った${RBENV_VERSION}を返し、


  3. rbenv-whichがそのバージョンに対応する${RBENV_COMMAND_PATH}を返し、


  4. rbenv-execがそのコマンドを実際に実行する
    というかんじ。なかなか深い…。


ということは

特にruby特有の仕組みを使っておらず、ほぼシェルスクリプトだけで実現されているので、他の似たようなスクリプト言語でもこの仕組みは適用できそう


ほほう。

現にこの方はPerlのバージョン管理として置換に成功しているようだ。

改めてphpenvを読み直すと、

RBENV_REPO="https://github.com/sstephenson/rbenv.git"

if [ "$UPDATE" = "yes" ]; then
echo "Updating phpenv in $PHPENV_ROOT"
update_phpenv "$PHPENV_ROOT"
else
echo "Installing phpenv in $PHPENV_ROOT"
if [ "$CHECKOUT" = "yes" ]; then
clone_rbenv "$PHPENV_ROOT"
sed -i -e 's/rbenv/phpenv/g' "$PHPENV_ROOT"/completions/rbenv.{bash,zsh}
sed -i -s 's/\.rbenv-version/.phpenv-version/g' "$PHPENV_ROOT"/libexec/rbenv-local
sed -i -s 's/\.rbenv-version/.phpenv-version/g' "$PHPENV_ROOT"/libexec/rbenv-version-file
sed -i -s 's/\.ruby-version/.php-version/g' "$PHPENV_ROOT"/libexec/rbenv-local
sed -i -s 's/\.ruby-version/.php-version/g' "$PHPENV_ROOT"/libexec/rbenv-version-file
sed -i -e 's/\(^\|[^/]\)rbenv/\1phpenv/g' "$PHPENV_ROOT"/libexec/rbenv-init
sed -i -e 's/\phpenv-commands/rbenv-commands/g' "$PHPENV_ROOT"/libexec/rbenv-init
sed -i -e 's/\Ruby/PHP/g' "$PHPENV_ROOT"/libexec/rbenv-which
fi
fi

create_phpenv_bin "$PHPENV_ROOT"

ラッパーだ。なるほど。

先ほどの記事に倣ってphpenvを作りなおしてみる。

.bashrc/.zshrcへのPATH設定は残したままにしてある。

元のphpenvはbrew uninstallなりで消しておく。

# make repo

$ mkdir ~/.phpenv
$ cd ~/.phpenv
$ git init
$ hub create phpenv
Updating origin
created repository: laprasdrum/phpenv

# copy rbenv
$ git clone git://github.com/sstephenson/rbenv.git ~/.tmp
$ cp ~/.tmp/* ~/.phpenv
$ cp ~/.tmp/.gitignore .travis.yml ~/.phpenv

# s/rbenv/phpenv/g
$ for i in $(find ~/.phpenv/libexec -name 'rbenv*'); do perl -pe 's/rbenv/phpenv/g;s/RBENV/PHPENV/g;s/Ruby/PHP/g’ $i > ${i/rbenv/phpenv}; chmod u+x ${i/rbenv/phpenv}; done

# symbolic link
$ ln -s ../libexec/phpenv .phpenv/bin
$ which phpenv
/Users/laprasDrum/.phpenv/bin/phpenv

$ phpenv versions
* system (set by /Users/laprasDrum/.phpenv/version)


再々インストール

$ php-build 5.5.8 ~/.phpenv/versions/5.5.8

$ phpenv versions
* system (set by /Users/laprasDrum/.phpenv/version)
5.5.8
$ phpenv global 5.5.8
$ phpenv rehash
system
* 5.5.8 (set by /Users/laprasDrum/.phpenv/version)

$ php -v
PHP 5.5.8 (cli) (built: May 10 2014 14:38:46)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies
with Zend OPcache v7.0.3-dev, Copyright (c) 1999-2013, by Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans

( ^ω^)おっ

$ php-build 5.4.25 ~/.phpenv/versions/5.4.25

$ phpenv versions
system
5.4.25
* 5.5.8 (set by /Users/laprasDrum/.phpenv/version)
$ phpenv global 5.4.25
$ phpenv rehash
$ php -v
PHP 5.4.25 (cli) (built: May 10 2014 14:51:42)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans

laprasdrum/phpenv

✌(・ω・)