Tips

phpbrewでphp7.3.33のインストール時のエラーと解決策

phpbrewで現時点で少し古めのphp7.3.33をインストールした際に、たくさんのエラーが出てそれを乗り越えたのでお伝えします。一つエラーを消すと、新たなエラーが出て、それに対処していくと、結果的にオプションをたくさん付けることになりました。

使用した環境

この記事は以下の記事でMac上にWordPress環境を構築する中で、PHPをインストールする際に試行錯誤したものです。

M2 MacでWordPressの開発環境構築手順!MAMPは使うな!M2のMacBook AirにてWordPressの開発環境を構築したので手順をご紹介します。MAMPを使わずにHomebrew、PHP...
端末 M2 MacBook Air(2022)
Mac OS 13.2.1(22D68)
homebrew 4.0.20
phpbrew 2.1.0
インストールするPHP 7.3.33

必要なライブラリがなくて怒られる

最初はシンプルに以下のようにしてみました。

しかし色々エラーが出て失敗しました。

以下のようなエラーに注目しました。

openssl@1.1やpcre2はphpbrew(PHP8.1)をインストールする時にインストールされていましたが、7.3.33とは使うバージョンが違うようですね。

なので、素直に上記で表示されたものHomebrewでインストールします。以下を参考にしました。

phpbrew のインストールでエラー

zlibの指定をする

再度実行します。

先ほどのエラーは消えましたが、以下のようなエラーが出ました。

なので、以下を参考に

PHPBrewでPHPをインストールするときにzlibでエラーが出る場合

としたところ、

というようなエラーが出ました。

とパスは表示されるのでzlibはインストールされていると思っていたのですが、インストールされていなかったようです。

なので、

でインストールします。

改めて以下をするとこのエラーは無くなりました。

でも、zlibをインストール後も、以下となるのが不思議です。

openssl@1.1の指定

しかし今度は以下のエラーが出ます。

なので、今度は以下の記事に従って次のようにします。

phpbrew で PHP 7.1 / 8.0 をインストールした( + openssl / + gd )

これでこのエラーは消えました。opensslは上記記事や以下によると、バージョンは3ではなくて良さそうす。というか3だとダメというように読めます。

要件

1.1はphpbrewをインストールした時に一緒にインストールされました。3は先ほどの手順で無いと怒られたので入れました。なぜ使わないのに入れさせられたかがわかりません。

あと、パスの指定の仕方はもしかしたら、zlibと同じく "$(brew --prefix openssl@1.1)"でも良いかもしれませんが、試していません。参考にした記事のままやっているから、この辺りの統一感は無いかもしれません。

pcre2の指定

次も、長いエラーが出ますが、ポイントとなるのは以下の部分です。

以下に従って次のようにしてみます。

M1 Macでarm64のHomebrewとPHPBrewでPHP8.0の環境作ってベンチながす

しかし、エラーは変わりません。

どうやら

pkg-config への移行

インストール手順

によると、PHP7.3だと--with-external-pcre ではなく、--with-pcre-regexを使うようです。そして7.3以降はPCRE2が必須とのことです。でも、PCREの2がつかない方は、先ほど怒られたので入れました。opensslの3と同じく使わないのになぜ入れさせるのか不思議です。

以下のようにすると

インストールできました。出力の最下部に以下のように表示されます。

ただ、以下のようなWarning?は残ったままなのが少し気持ち悪いです。

apxs2の指定

参考にしていたページで、Apacheとの連携で、libphp.soという名前(バージョン番号が入る場合もある)のファイルを読み込む部分を、Apacheの設定ファイル、httpd.confに記述する手順があったのですが、そのファイルがどこにあるのかどうしてもわかりません。

色々調べてわかったことなのですが、libphp.soはphpのビルド時にあるオプションを指定しないと生成されないようです。

Apache2 support

apxs2というオプションを指定する必要があるそうです。

仕方ないので、一度アンインストールしてインストールしなおします。以下でアンインストールします。

この際、確実に使うであろう、MySQLやXdebugに関わるオプションも指定して、再インストールしました。

後で分かったことですが、 +debug をつけてもXdebugは使えるようにはならならないということがわかりました。それについては以下に記載しています。

MacのPHPbrewでのXdebugの設定法とVScodeでの使い方MacでPHPbrewでPHPの環境を構築していますが、Xdebugを導入しVScodeでの開発の効率を上げることにしました。設定方法を...

そして、以下で、このオプションはXdebugとは無関係で、このオプション無しでもXdebugは正常に使えることがわかりました。

PHPbrewでの8.2.8のインストールとバージョン切り替え方法PHPbrewで執筆時点で最新版のPHP8.2.8をインストールしました。以前に7.3.33をインストールしていたので、今回2バージョン...

すると、以下のようなエラーが出ました。

これはlibxml2以外のイブラリについても出たので、かなりたくさん出ました。

以下によるとHomebrew関連のエラーのようです。カレントディレクトリが存在しない場合は発生するそうです。

ターミナルで、shell-init: error retrieving current directory: getcwd: cannot access parent directories: というエラーが出た場合の対処

というのは、先ほどphpをアンインストールしましたが、その時削除されたディレクトリがカレントになっていたからです。なので、ホームディレクトリに戻って同じコマンドを実行するとこのエラーは消えます。

もう一種類出たエラーがこちらです。

+mysql +debug +apxs2 などのオプションは -with-pcre-regex より前にないとダメっぽいです。もしかしたら、 -- より前にしないとダメなのかもしれません。なのでこうします。

するとまた違ったエラーが出ました。

apxsのパスが通ってないのかな、と思って確認しました。

どこにあるapxsかも調べたら、ちゃんとHomebrewによってインストールされたものでした。

しかも、

httpdというディレクトリの配下にあるということは、Apacheと一緒にHomebrewでインストールされたということです。というかApacheの一部なのでしょう。

よくわからないですが、明示的にapxsをフルパスで指定してみました。

これでようやくインストール成功しました。

後で分かったことですが、ここでのパスの指定もフルパスでなくて "$(which apxs)" でよいことがわかりました。それについては、先程紹介した、8.2.8をインストールした際の記事に記載しています。

MySQLのオプションをつけたから、それ関連の表示が出ています。

ただ相変わらず以下のWarning?は表示されます。

httpd.confが勝手に修正されてる

さて、httpd.confにlibphp.soを読み込む設定を書き込むぞと思って、httpd.confを開いてみました。すると、なんとその設定が書き込まれていることを発見しました。

httpd.confのタイムスタンプはちょうどインストールが完了したくらいの時刻でした。さらに、同じディレクトリに、httpd.conf.bakというファイルがありました。

diffをとってみたら、

この部分だけ追記されていました。

libphp7.3.33.soのタイムスタンプもインストール完了時の時刻でした。これもそのタイミングで生成されたということです。

これらの自動処理が、phpbrewによってなされたものなのか、phpbrewを使わなくても、PHPをビルドしたらなされるものなのかはわかりません。

とはいえ、これはそのまま使わせてもらうことにします。

ApacheをPHPより先にインストールするべきということ

PHPのインストール時にhttpd.confが書き換わるということは、つまり、PHPより先にApacheをインストールしておく必要があるということです。

もし、Apacheをインストールする前に、phpbrewをインストールしたら、もしかしたら、MacにプリインストールされているApacheのhttpd.confが書き換わるのかもしれません。やってないのでわからないですが。

ApecheとPHPの連携の仕方は3種類ある

apxs2のオプションについて調べている時に学んだのですが、ApacheとPHPの連携の仕方は3種類あります。

  1. モジュール方式(静的)
  2. モジュール方式(動的)
  3. CGI方式

3のCGI方式は、ApacheとPHPが別プロセスとして起動し、互いにやりとりをして動きます。それに対し、1、2のモジュール方式はApacheのプロセスの中でPHPが動きます。なので、一つのプロセスとして動きます。したがって、CGIよりもモジュールの方が速いと思われます。少し古いですが以下の記事にデータがあります。実際は負荷が高い状況でないとモジュール方式の真価は発揮されないようですが。また、細かい話をするとFactCGIというCGIを軽快にしたものもあります。

PHPモジュールモードとCGIモードの違いとパフォーマンスの差を検証

1の静的の方は、Apacheのコンパイル時にPHPのプログラムが、Apacheのバイナリーであるhttpdの中に埋め込まれるそうです。それに対し、2の動的の方はhttpdのバイナリーにはPHPは含まれず、外部から起動時に読み込まれます。当然、一つのバイナリーになっている静的の方が高速だと言われていますが、ベンチマークのデータは見当たりませんでした。

静的モジュールと動的モジュール

Shared Apache 2.0 Module vs Static Apache Module

モジュール方式(静的)にもデメリットはあります。PHPのバージョンを変える時に、Apacheもビルドしなおす必要があります。モジュール方式(動的)であれば、httpd.confで指定するファイルを変えるだけで切り替えることが可能です。

私は開発環境でPHPのバージョンは頻繁に切り替える可能性があるので、当記事の手順ではモジュール方式(動的)を採用しました。本番環境で大規模なサイトを運営する場合は、モジュール方式(静的)を採用してパフォーマンスの恩恵を受けてもいいかもしれませんね。

apxsというのはモジュール方式(動的)で使うための拡張モジュールをビルドしてインストールするためのツールだそうです。

apxs - APache eXtenSion tool

ちなみに、phpbrewでモジュール方式(静的)で使うための手順は見つけられませんでした。できるのかな。

実際の環境のApacheが、PHPを静的に取り込んでいるか、動的に取り込んでいるか確認するコマンドがあります。

staticは静的、sharedは動的ということです。31行目でPHPは動的ということがわかります。以下を参考にしました。

Apacheに組み込まれているモジュールの一覧を取得する(httpd -l,httpd -M)

拡張機能でインストールできるもの、できないもの

最初、mysql、xdebug、apxs2のオプションを指定せずにphpをインストールしました。というのは、公式の以下の記載から後からいくらでも追加で入れられるだろうと考えていました。

Installing Extension - The Most Simple Way

まずxdebugで試してみました。

インストールする前に対象のPHPにセットしておく必要があります。というのは

後で分かったことですが、PHPがバージョンごとにインストールされているディレクトリ配下に拡張機能も配置されるので、どのPHPのバージョンに対してインストールするか指定する必要があるためです。

/Users/xxxxx/.phpbrew/build/php-7.3.33/ext/xdebug/

なので、複数のPHPのバージョンがあってそれぞれでXdebugを使いたいなら、それぞれに対してインストールする必要があるということです。

早速インストールしてみます。以下で詳しく書きましたが、無事この方法でインストールできました。

MacのPHPbrewでのXdebugの設定法とVScodeでの使い方MacでPHPbrewでPHPの環境を構築していますが、Xdebugを導入しVScodeでの開発の効率を上げることにしました。設定方法を...

この流れでapxs2やmysqlについてもインストールできるかやってみました。

しかし、上記のようにエラーが出てインストールできませんでした。

apxs2はおそらく、PHPの拡張機能というわけではなく、Apache側の持ち物だからでしょう。mysqlについてはよくわかりませんが、PHPの拡張機能という位置付けではないのでしょう。

この辺りはやはり、PHPのインストール時にオプションで指定しておくべきということでしょう。結局PHPをインストールし直したので、オプションで指定してインストールすることになりました。

Rubyに比べてPHPってやっぱりごちゃごちゃしてる

phpbrewに相当するRubyのrbenvでRubyをインストールする時って、こんなにハマった経験はありません。トリッキーなオプションを設定したこともなく、何事もスマートに済む印象があります。

phpbrewの問題かなと最初思ったのですが、これってPHPという言語のエコシステム全体の問題なのではないかなと思います。