PHPbrewではじめるPHPのバージョン管理
目次
MacOS を Monterey にアップデートしてからターミナル上で php
コマンドや composer
コマンドが実行できなくなってしまいました。調べてみると Monterey から PHP から標準インストールされなくなったようです。そのため、PHP を自前でインストールする必要があります。普通にインストールしてもよいのですが、せっかくならバージョン管理できるようになろうと思い、調べてみると PHP のバージョン管理では、PHPbrew というのが良いらしいので導入してみました。
PHPbrew とは
PHPbrew とは、 PHPのパッケージ管理ツールです。 Node.js でいう nodenv や volta とかと同じ立ち位置です。しかし、PHP のバージョンには nodenv のようにグローバル と ローカルという概念はなく、バージョンを変更したらOS全体でバージョンが変更されるようです。
必要要件
xcode と autoconf、pkg-config のインストール(xcodeは以前インストールしていればいらない)が必要です。インストールしてない方は以下のコマンドでインストールできます。
xcode-select --install
brew install autoconf pkg-config
次にBuilding development versions of PHPと言うことで、PHPを任意のソースツリーからビルドできるようにするには、追加の依存関係のセットが必要らしいです。
brew install bison re2c
GETTING STARTED
インストール
curl -L -O https://github.com/phpbrew/phpbrew/releases/latest/download/phpbrew.phar
chmod +x phpbrew.phar
# $PATH の通っているディレクトリにファイルを移動します
sudo mv phpbrew.phar /usr/local/bin/phpbrew
初期化処理
シェルで bash スクリプトを初期化します。
phpbrew init
↑ コマンドを実行して、成功すると以下のようになります。
Initialization successfully finished!
<=====================================================>
Phpbrew environment is initialized, required directories are created under
/Users/username/.phpbrew
Paste the following line(s) to the end of your ~/.bashrc and start a
new shell, phpbrew should be up and fully functional from there:
source /Users/username/.phpbrew/bashrc
To enable PHP version info in your shell prompt, please set PHPBREW_SET_PROMPT=1
in your `~/.bashrc` before you source `~/.phpbrew/bashrc`
export PHPBREW_SET_PROMPT=1
To enable .phpbrewrc file searching, please export the following variable:
export PHPBREW_RC_ENABLE=1
For further instructions, simply run `phpbrew` to see the help message.
Enjoy phpbrew at $HOME!!
<=====================================================>
と出てくるので↓を実行
source /Users/username/.phpbrew/bashrc
## ↓でもok
source ~/.phpbrew/bashrc
.zshrc に以下を追加すると初期化処理をターミナル起動時に自動でやってくれます。
source $HOME/.phpbrew/bashrc
バリアントとは
公式から引用すると
PHPBrew は設定オプションをアレンジします。バリアント名を指定するだけで、 phpbrew がインクルードパスとビルドオプションを検出し、 設定を行ないます。
PHPBrew はデフォルトの variant といくつかの仮想 variant を提供しています。よく使われる variant を含むデフォルト variant と、variant セットを定義する仮想 variant で、ひとつの仮想 variant を使って複数の variant を一度に有効にすることができます。
これらの variant に何が含まれているかを調べるには、 phpbrew variants を実行してこれらの variant をリストアップします。
つまり、バリアントとはPHPをインストールする際に必要なパッケージのことで、以下のようにインストール時のコマンドと一緒に記述することで一緒にインストールしてくれるということです。
phpbrew install 5.4.1 +pgsql+pdo
そして、 仮想 variant とはよく使用する variant をパッケージとしてまとめたもの。以下のコマンドで確認できます。
phpbrew variants
Variants:
all, apxs2, bcmath, bz2, calendar, cgi, cli, ctype, curl, dba, debug, dom,
dtrace, editline, embed, exif, fileinfo, filter, fpm, ftp, gcov, gd,
gettext, gmp, hash, iconv, imap, inifile, inline, intl, ipc, ipv6, json,
kerberos, ldap, libgcc, mbregex, mbstring, mcrypt, mhash, mysql, opcache,
openssl, pcntl, pcre, pdo, pear, pgsql, phar, phpdbg, posix, readline,
session, soap, sockets, sodium, sqlite, static, tidy, tokenizer, wddx,
xml, xmlrpc, zip, zlib, zts
Virtual variants:
dbs: sqlite, mysql, pgsql, pdo
mb: mbstring, mbregex
neutral:
small: bz2, cli, dom, filter, ipc, json, mbregex, mbstring, pcre, phar,
posix, readline, xml, curl, openssl
default: bcmath, bz2, calendar, cli, ctype, dom, fileinfo, filter, ipc,
json, mbregex, mbstring, mhash, pcntl, pcre, pdo, pear, phar, posix,
readline, sockets, tokenizer, xml, curl, openssl, zip
everything: dba, ipv6, dom, calendar, wddx, static, inifile, inline, cli,
ftp, filter, gcov, zts, json, hash, exif, mbstring, mbregex, libgcc,
pdo, posix, embed, sockets, debug, phpdbg, zip, bcmath, fileinfo, ctype,
cgi, soap, pcntl, phar, session, tokenizer, opcache, imap, ldap, tidy,
kerberos, xmlrpc, fpm, dtrace, pcre, mhash, mcrypt, zlib, curl, readline,
editline, gd, intl, sodium, openssl, mysql, sqlite, pgsql, xml, gettext,
iconv, bz2, ipc, gmp, pear
Using variants to build PHP:
phpbrew install php-5.3.10 +default
phpbrew install php-5.3.10 +mysql +pdo
phpbrew install php-5.3.10 +mysql +pdo +apxs2
phpbrew install php-5.3.10 +mysql +pdo +apxs2=/usr/bin/apxs2
基本操作
PHP のバージョンを一覧する:
phpbrew known
Read local release list (last update: 2022-02-24 03:14:45 UTC).
You can run `phpbrew update` or `phpbrew known --update` to get a newer release list.
8.1: 8.1.3, 8.1.2, 8.1.1, 8.1.0 ...
8.0: 8.0.16, 8.0.15, 8.0.14, 8.0.13, 8.0.12, 8.0.11, 8.0.10, 8.0.9 ...
7.4: 7.4.28, 7.4.27, 7.4.26, 7.4.25, 7.4.24, 7.4.23, 7.4.22, 7.4.21 ...
7.3: 7.3.33, 7.3.32, 7.3.31, 7.3.30, 7.3.29, 7.3.28, 7.3.27, 7.3.26 ...
7.2: 7.2.34, 7.2.33, 7.2.32, 7.2.31, 7.2.30, 7.2.29, 7.2.28, 7.2.27 ...
7.1: 7.1.33, 7.1.32, 7.1.31, 7.1.30, 7.1.29, 7.1.28, 7.1.27, 7.1.26 ...
7.0: 7.0.33, 7.0.32 ...
現在インストールされている PHP バージョンが、php 8.1.3で phpbrew known を実行すると、 Deprecated: strpos(): のようなwarningが出まくるので注意です。7.3.33 に落とすとでこのwarningは出なくなりました。
PHPのビルド(インストール)
phpbrew install 7.4.25 +default
ビルド(インストール)が成功すると、以下のようになります。
config-set succeeded
config-set succeeded
config-set succeeded
Enabling pear auto-discover...
config-set succeeded
Congratulations! Now you have PHP with 7.4.25 as php-7.4.25
* To configure your installed PHP further, you can edit the config file at
/Users/uirikuto/.phpbrew/php/php-7.4.25/etc/php.ini
* WARNING:
You haven't setup your .bashrc file to load phpbrew shell script yet!
Please run 'phpbrew init' to see the steps!
To use the newly built PHP, try the line(s) below:
$ phpbrew use php-7.4.25
Or you can use switch command to switch your default php to php-7.4.25:
$ phpbrew switch php-7.4.25
Enjoy!
インストールされているPHPの一覧
phpbrew list
* (system)
php-7.4.25
use (一時的なバージョンの切り替え)
phpbrew use php-7.4.25
switch (デフォルトで使用するバージョンを切り替える)
phpbrew switch php-7.4.25
phpbrewを使用するのをやめる(システムデフォルトのPHPを使用)
phpbrew off
トラブルシューティング
php 8.0.16 をインストールしようとしたら下記エラーがでました。
phpbrew install 8.0.16 +default
===> phpbrew will now build 8.0.16
===> Loading and resolving variants...
Homebrew prefix "/usr/local/opt/libxml2" does not exist.
Homebrew prefix "/usr/local/opt/bzip2" does not exist.
Homebrew prefix "/usr/local/opt/mhash" does not exist.
Homebrew prefix "/usr/local/opt/openssl@3" does not exist.
Downloading https://www.php.net/distributions/php-8.0.16.tar.bz2 via curl extension
[==================================================================] 12.88/12.88MB 100%
===> Extracting /Users/username/.phpbrew/distfiles/php-8.0.16.tar.bz2 to /Users/uirikuto/.phpbrew/build/tmp.1645877003/php-8.0.16
===> Moving /Users/username/.phpbrew/build/tmp.1645877601/php-8.0.16 to /Users/uirikuto/.phpbrew/build/php-8.0.16
===> Checking patches...
Checking patch for replace apache php module name with custom version name
Checking patch for replace freetype-config with pkg-config on php older than 7.4
===> Configuring 8.0.16...
Use tail command to see what's going on:
$ tail -F '/Users/username/.phpbrew/build/php-8.0.16/build.log'
Error: Configure failed:
The last 5 lines in the log file:
installed software in a non-standard prefix.
Alternatively, you may set the environment variables OPENSSL_CFLAGS
and OPENSSL_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
Please checkout the build log file for more details:
tail /Users/username/.phpbrew/build/php-8.0.16/build.lo
ログを確認してみると、openssl というパッケージが足りてないと言われました。
tail /Users/username/.phpbrew/build/php-8.0.16/build.log
configure: error: Package requirements (openssl >= 1.0.1) were not met:
No package 'openssl' found
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
Alternatively, you may set the environment variables OPENSSL_CFLAGS
and OPENSSL_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
とりあえず、現在のopensslのバージョンを確認してみました。
openssl version
LibreSSL 2.8.3
MacのHigh Sierraから、デフォルトのOpenSSLがOpenSSLからLibreSSLになっているため、LibreSSL が使用されているようです。
詳しくはこちら
とりあえず、brew list で現在homebrew でインストールしているパッケージを確認してみると、openssl@1.1 はインストールされているようです。
brew list
==> Formulae
aom curl glib jpeg libpng libxcb oniguruma re2c
apr docbook gmp jpeg-xl libpq libxdmcp openexr readline
apr-util docbook-xsl gnu-getopt krb5 libpthread-stubs libxext openjpeg rtmpdump
argon2 emacs gnutls libavif libsodium libxrender openldap shared-mime-info
aspell fontconfig gobject-introspection libde265 libspiro libzip openssl@1.1 sqlite
autoconf freetds graphite2 libev libssh2 little-cms2 p11-kit tidy-html5
bdw-gc freetype guile libevent libtasn1 lzo pango unbound
bison fribidi harfbuzz libffi libtiff m4 pcre unixodbc
brotli gd icu4c libheif libtool mpdecimal pcre2 webp
c-ares gdbm imagemagick libidn libuninameslist nettle php x265
ca-certificates gettext imath libidn2 libunistring nghttp2 php@7.3 xmlto
cairo ghostscript jansson liblqr libvmaf node-build pixman xorgproto
cask giflib jbig2dec libnghttp2 libx11 nodebrew pkg-config xz
coreutils git jemalloc libomp libxau nodenv python@3.9 zstd
==> Casks
alfred cheatsheet dropbox google-backup-and-sync iterm2 sketch zoom
biscuit clipy firefox google-japanese-ime mamp visual-studio-code
一応インストールしてみます。
brew install openssl
インストール後、もう一度 php 8.0.16 をインストールすると、今度は以下のエラーが…
phpbrew install 8.0.16 +default
===> phpbrew will now build 8.0.16
===> Loading and resolving variants...
Homebrew prefix "/usr/local/opt/libxml2" does not exist.
Homebrew prefix "/usr/local/opt/bzip2" does not exist.
Homebrew prefix "/usr/local/opt/mhash" does not exist.
Checking distribution checksum...
Checksum matched: f49f8181ee29463a0d23a0c65969e92d58fee8ac564df917cff58e48d65e1849
===> Distribution file was successfully extracted, skipping...
===> Checking patches...
Checking patch for replace apache php module name with custom version name
Checking patch for replace freetype-config with pkg-config on php older than 7.4
Found existing build.log, renaming it to /Users/username/.phpbrew/build/php-8.0.16/build.log.1645877638
===> Configuring 8.0.16...
Use tail command to see what's going on:
$ tail -F '/Users/username/.phpbrew/build/php-8.0.16/build.log'
Error: Configure failed:
The last 5 lines in the log file:
checking for ZLIB support... no
checking whether to enable bc style precision math functions... yes
checking for BZip2 support... yes
checking for BZip2 in default path... not found
configure: error: Please reinstall the BZip2 distribution
Please checkout the build log file for more details:
tail /Users/username/.phpbrew/build/php-8.0.16/build.log
まず、最初の Homebrew prefix 〇〇 というところから必要パッケージが足りてないのではないかと思い homebrew でインストールしました。
brew install libxml2 bzip2 mhash
再度、php 8.0.16 をインストールしてみると、またエラーが…
phpbrew install 8.0.16 +default
===> phpbrew will now build 8.0.16
===> Loading and resolving variants...
Checking distribution checksum...
Checksum matched: f49f8181ee29463a0d23a0c65969e92d58fee8ac564df917cff58e48d65e1849
===> Distribution file was successfully extracted, skipping...
===> Checking patches...
Checking patch for replace apache php module name with custom version name
Checking patch for replace freetype-config with pkg-config on php older than 7.4
Found existing build.log, renaming it to /Users/username/.phpbrew/build/php-8.0.16/build.log.1645878692
===> Configuring 8.0.16...
Use tail command to see what's going on:
$ tail -F '/Users/username/.phpbrew/build/php-8.0.16/build.log'
===> Checking patches...
Checking patch for php5.3.x on 64bit machine when intl is enabled.
Checking patch for openssl dso linking patch
2 changes patched.
Checking patch for php5.6 with openssl 1.1.x patch.
===> Building...
Error: Make failed:
The last 5 lines in the log file:
/usr/local/Cellar/openssl@3/3.0.1/include/openssl/rsa.h:289:29: note: passing argument to parameter 'rsa' here
RSA *rsa, int padding);
^
108 warnings and 1 error generated.
make: *** [ext/openssl/openssl.lo] Error 1
Please checkout the build log file for more details:
tail /Users/username/.phpbrew/build/php-8.0.16/build.log
ログを見ても、よくわかりません。。。
tail /Users/usename/.phpbrew/build/php-8.0.16/build.log
# define OSSL_DEPRECATED(since) __attribute__((deprecated))
^
/Users/username/.phpbrew/build/php-8.0.16/ext/openssl/openssl.c:6393:6: warning: passing 'const struct rsa_st *' to parameter of type 'RSA *' (aka 'struct rsa_st *') discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers]
EVP_PKEY_get0_RSA(pkey),
^~~~~~~~~~~~~~~~~~~~~~~
/usr/local/Cellar/openssl@3/3.0.1/include/openssl/rsa.h:289:29: note: passing argument to parameter 'rsa' here
RSA *rsa, int padding);
^
108 warnings and 1 error generated.
make: *** [ext/openssl/openssl.lo] Error 1
調べると、以下の記事がヒットしましたが、一旦opensslがまだhomebrewでインストールしたほうを参照してくれていないのではないかと思ったので whtch
コマンドで確認します。
which openssl
/usr/bin/openssl
openssl version
LibreSSL 2.8.3
そうするとやっぱり思ったとおりで、 openssl の参照先が違っていました。なので、openssl@3のパスを通してあげます。
echo 'export PATH="/usr/local/opt/openssl@3/bin:$PATH"' >> ~/.zshrc
ターミナルを立ち上げ直すか、souce ~/.zshrc
をしてから確認すると、v3が参照されるようになっている
openssl version
OpenSSL 3.0.1 14 Dec 2021 (Library: OpenSSL 3.0.1 14 Dec 2021)
ここで再度、phpのインストールをしてみるが、同じエラー…。openssl v3 を参照しているのが駄目なのかと思い、.zshrc の openssl@3 を @1.1 に変更します。
# ~/.zshrc
export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"
openssl がv1.1 を参照していることを確認して再度 php のインストールを試みるも解決せず…
openssl version
OpenSSL 1.1.1m 14 Dec 2021
最終的な解決策として、.zshrc に以下を追加して解決でした。
export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig"
このブログ記事に助けられました。ありがとうございます?
phpbrew install 7.4.25 +default
===> phpbrew will now build 7.4.25
===> Loading and resolving variants...
Homebrew prefix "/usr/local/opt/openssl@3" does not exist.
Checking distribution checksum...
Checksum matched: 27992570caf3e2e5323ab7b37853c44c1529b1d31ea94d9776efa91d5a781313
===> Distribution file was successfully extracted, skipping...
===> Checking patches...
Checking patch for replace apache php module name with custom version name
Checking patch for replace freetype-config with pkg-config on php older than 7.4
Found existing build.log, renaming it to /Users/uirikuto/.phpbrew/build/php-7.4.25/build.log.1645882512
===> Configuring 7.4.25...
Use tail command to see what's going on:
$ tail -F '/Users/uirikuto/.phpbrew/build/php-7.4.25/build.log'
===> Checking patches...
Checking patch for php5.3.x on 64bit machine when intl is enabled.
Checking patch for openssl dso linking patch
0 changes patched.
Checking patch for php5.6 with openssl 1.1.x patch.
===> Building...
Build finished: 7.4 minutes.
Installing...
---> Creating php-fpm.conf
---> Creating php.ini
---> Copying /Users/username/.phpbrew/build/php-7.4.25/php.ini-development
---> Found date.timezone is not set, patching...
Initializing pear config...
config-set succeeded
config-set succeeded
config-set succeeded
Enabling pear auto-discover...
config-set succeeded
Congratulations! Now you have PHP with 7.4.25 as php-7.4.25
* To configure your installed PHP further, you can edit the config file at
/Users/username/.phpbrew/php/php-7.4.25/etc/php.ini
* WARNING:
You haven't setup your .bashrc file to load phpbrew shell script yet!
Please run 'phpbrew init' to see the steps!
To use the newly built PHP, try the line(s) below:
$ phpbrew use php-7.4.25
Or you can use switch command to switch your default php to php-7.4.25:
$ phpbrew switch php-7.4.25
Enjoy!
openssl@3 はいらなくなったのでアンインストール済みです。
brew uninstall openssl@3
Uninstalling /usr/local/Cellar/openssl@3/3.0.1... (6,420 files, 28.1MB)
Warning: The following openssl@3 configuration files have not been removed!
If desired, remove them manually with `rm -rf`:
/usr/local/etc/openssl@3
/usr/local/etc/openssl@3/cert.pem
/usr/local/etc/openssl@3/certs
/usr/local/etc/openssl@3/ct_log_list.cnf
/usr/local/etc/openssl@3/ct_log_list.cnf.dist
/usr/local/etc/openssl@3/misc
/usr/local/etc/openssl@3/misc/CA.pl
/usr/local/etc/openssl@3/misc/tsget
/usr/local/etc/openssl@3/misc/tsget.pl
/usr/local/etc/openssl@3/openssl.cnf
/usr/local/etc/openssl@3/openssl.cnf.dist
/usr/local/etc/openssl@3/private
Warning: The following may be openssl@3 configuration files and have not been removed!
If desired, remove them manually with `rm -rf`:
/usr/local/etc/openssl@1.1
~/develop/workspace/phpbrew-test
❯ brew list
==> Formulae
aom curl gmp krb5 libsodium libxrender openldap sqlite
apr docbook gnu-getopt libavif libspiro libzip openssl@1.1 tidy-html5
apr-util docbook-xsl gnutls libde265 libssh2 little-cms2 p11-kit unbound
argon2 emacs gobject-introspection libev libtasn1 lzo pango unixodbc
aspell fontconfig graphite2 libevent libtiff m4 pcre webp
autoconf freetds guile libffi libtool mhash pcre2 x265
bdw-gc freetype harfbuzz libheif libuninameslist mpdecimal php xmlto
bison fribidi icu4c libidn libunistring nettle php@7.3 xorgproto
brotli gd imagemagick libidn2 libvmaf nghttp2 pixman xz
bzip2 gdbm imath liblqr libx11 node-build pkg-config zstd
c-ares gettext jansson libnghttp2 libxau nodebrew python@3.9
ca-certificates ghostscript jbig2dec libomp libxcb nodenv re2c
cairo giflib jemalloc libpng libxdmcp oniguruma readline
cask git jpeg libpq libxext openexr rtmpdump
coreutils glib jpeg-xl libpthread-stubs libxml2 openjpeg shared-mime-info
==> Casks
alfred cheatsheet dropbox google-backup-and-sync iterm2 sketch zoom
biscuit clipy firefox google-japanese-ime mamp visual-studio-code
~/develop/workspace/phpbrew-test
❯ rm -rf /usr/local/etc/openssl@3
~/develop/workspace/phpbrew-test
❯ rm -rf /usr/local/etc/openssl@3/cert.pem
~/develop/workspace/phpbrew-test
❯ rm -rf /usr/local/etc/openssl@3/certs
~/develop/workspace/phpbrew-test
❯ rm -rf /usr/local/etc/openssl@3/ct_log_list.cnf
~/develop/workspace/phpbrew-test
❯ rm -rf /usr/local/etc/openssl@3/ct_log_list.cnf.dist
~/develop/workspace/phpbrew-test
❯ rm -rf /usr/local/etc/openssl@3/misc
~/develop/workspace/phpbrew-test
❯ rm -rf /usr/local/etc/openssl@3/misc/CA.pl
~/develop/workspace/phpbrew-test
❯ rm -rf /usr/local/etc/openssl@3/misc/tsget
~/develop/workspace/phpbrew-test
❯ rm -rf /usr/local/etc/openssl@3/misc/tsget.pl
~/develop/workspace/phpbrew-test
❯ rm -rf /usr/local/etc/openssl@3/openssl.cnf
~/develop/workspace/phpbrew-test
❯ rm -rf /usr/local/etc/openssl@3/openssl.cnf.dist
~/develop/workspace/phpbrew-test
❯ rm -rf /usr/local/etc/openssl@3/private
まとめ
PHP のバージョン管理をするだけでエラーと格闘してとてもめんどくさかったですw PHPbrew に比べると、nodenv や volta は楽ちんでいいなと思いました。