|||||||||||||||||||||

なんぶ電子

- 更新: 

Debian11でPHP8をビルド、Apacheも

php.iniの設定

筆者は普段Debianを利用しているのですが、執筆時点では、通常のAPTのリポジトリでインストールできるバージョンは 7.4 です。

近年はPHPの8以上を要件とするライブラリも増えてきましたので、Debian11でPHP8をビルドしてみたいと思います。合わせてApacheサーバのビルドも必要になります。

Apacheのビルド

APTで build-essential インストールを終えているものとし、Apacheをビルドします。

Apacheから、httpd-2.4.54.tar.gz をダウンロードして展開します。

# cd /usr/local/src
# wget https://dlcdn.apache.org/httpd/httpd-2.4.54.tar.gz
# tar vzxf httpd-2.4.54.tar.gz
# cd httpd-2.4.54
# ./configure --enable-so
...
checking for APR... no

configureを実行すると、APRがないということです。INSTALLファイルを読むと、apr.apache.orgからダウンロードするようにとの事でした。

APRはプラットフォーム間の挙動差異を吸収してくれるツールのようです。configure -hで見てみても、これがない状態でビルドする方法はなさそうでした。

ダウンロードしたのち展開し、httpd-2.4.54ディレクトリにあるsrclibディレクトリの中に、バージョンを除去した形で移動させます。その後、--with-inculded-aprオプションをつけてconfigureを実行します。

# wget https://dlcdn.apache.org//apr/apr-1.7.0.tar.gz
# wget https://dlcdn.apache.org//apr/apr-util-1.6.1.tar.gz
# tar vzxf apr-1.7.0.tar.gz
# tar vzxf apr-util-1.6.1.tar.gz
# mv apr-1.7.0 httpd-2.4.54/srclib/apr
# mv apr-util-1.6.1 httpd-2.4.54/srclib/apr-util
# ./configure --enable-so --with-inculded-apr

PCREもが存在しないというエラーも出ました。PCREはPerl 5と同じ構文で正規表現を行うためのライブラリです。aptで「libpcre2-dev」をインストールしたところconfigureは通りましたが、ビルドでエラーになりました。PCRE2Project/pcre2から最新版をダウンロードしてビルドするのがいいと思いまいます。

make時に「 expat.h: そのようなファイルやディレクトリはありません 」というメッセージでエラーとなりました。こちらは「libexpat1-dev」をaptでインストールしたところ解消しました。。

デフォルトだとApacheバイナリ群は「/usr/local/apache2/」にインストールされます。設定ファイルはその中のconf/httpd.confとなっており、設定はすべてその中に記述します。APTからインストールした際のようなDebianのApache2の設定ディレクトリ群では設定をしないため、a2enmod等のコマンドは利用できません。

サーバーはbinディレクトリのapachectlから「 start 」や「 stop 」といった引数を渡してコントロールします。apachectlの他のコマンドについては公式ページに掲載されています。

公開するファイルの保存先であるhtdocsディレクトリも同じ場所に存在します。

コマンドを利用すれば起動はできますが、おそらくサービス(Systemd)として動かしたいと思います。これはAPT経由でインストールしたapacheサーバーのファイルを参考に次のようにしました。

apache2.service

[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=https://httpd.apache.org/docs/2.4/

[Service]
Type=forking
Environment=APACHE_STARTED_BY_SYSTEMD=true
ExecStart=/usr/local/apache2/bin/apachectl start
ExecStop=/usr/local/apache2/bin/apachectl stop
ExecReload=/usr/local/apach2/apachectl graceful
PrivateTmp=true
Restart=on-abort

[Install]
WantedBy=multi-user.target

このファイルを/etc/systemd/system/ディレクトリに配置します。その後「systemctl enable apache2」を実行して自動化させます。

デフォルト以外の場所にインストールした場合は、Execのパスに注意してください。

またAPTでインストールした際は、apacheはwww-dataというユーザー権限で動くのでその設定もします。

ユーザーを作成します。

# useradd -s /bin/false www-data

次に、httpd.confのUserとGroupにwww-dataを設定します。

httpd.conf

# User daemon
# Group daemon
User www-data
Group www-data

サービスを再起動させて状態を確認します。httpのプロセスのユーザーが設定したwww-dataになっているものがあれば正常です。一部のプロセスはrootになっています。

# ps aux | grep www-data

root     ... /usr/local/apache2/bin/httpd -k start
www-data ... /usr/local/apache2/bin/httpd -k start
...

PHPのビルド

PHPをビルドします。まず公式のインストールガイドにあるように--with-apxs2=/usr/local/apache2/bin/apxs指定します。apacheをビルドしたのはこのためです。

ここでは、LaravelのPHP要件を想定して、Laravelに必要で、デフォルトで有効にならない次の拡張ライブラリを設定します。

  • BCMath

    --enable-bcmath

  • cURL

    --with-curl

  • Mbstring

    --enable-mbstring

  • OpenSSL

    --with-openssl

  • PCRE

    公式のWebのドキュメントにはデフォルトでソースにバンドルされているPCREが利用されるとの記述があったので、なにも指定しなかったところ「 Unable to start pcre module in Unknown on line 0 」というエラーに遭遇しました。そこでapacheインストール時にビルドしたPCREを利用するように「--with-external-pcre=[ライブラリのディレクトリ」と指定しています。

  • PDO

    PDO自体は有効になっていますが、MySQL(MariaDB)をPDOで使うなら、--with-pdo-mysql を指定する必要があります。Postgreの場合は--with-pdo-pgsqlを指定します。また PDO ではなく mysqli を利用するには --with-mysqli を指定します。利用する可能性があるならすべて設定することも可能です。

    ここでは設定しませんが、他に必要になりそうなものは、gd(画像処理)などがあると思います。これらのオプションの詳細は「 configure -h 」から確認可能です。

MariadbやopenSSLの他必要なアプリをインストールしておきます。筆者の環境では他にpkg-configやlibxml2-dev、libssl-dev(openssl)、libsqlite3-dev、libcurl4-openssl-dev(curl)、libonig-dev(Oniguruma正規表現ライブラリ)、zlib1g-dev(圧縮ライブラリ)が必要になりました。

あと、デフォルトだとphp.iniを置く場所が/etcディレクトリではないようなので、これが気になるようなら、--with-config-file-path=/etc/ で保存先のディレクトリを指定しましょう。

# apt install mariadb-server openssl pkg-config ...
# wget https://www.php.net/distributions/php-8.1.9.tar.gz
# tar vzxf php-8.1.9.tar.gz
# cd php-8.1.9.tar.gz
# ./configure --with-apxs2=/usr/local/apache2/bin/apxs --enable-bcmath --with-curl --enable-mbstring --with-openssl --with-pdo-mysql --with-zlib --with-external-pcre=/usr/local/lib

# make 
# make test
# make install

make testを事項するように促されますので、実行します。おそらくいくつかは失敗するのではないかと思います。

これらの対処方法は@IT:「PHPテスト失敗の原因を追究する」が参考になります。

例えば次のようなエラーが出たとします。

Bug #78014 (Preloaded classes may depend on non-preloaded classes due to unresolved consts) [ext/opcache/tests/bug78014.phpt]

この時ソースディレクトリにある「ext/opcache/tests/bug78014.phpt」に定義されているテストが実行されます。その内容から状況を判断します。

今回は、opcache関連のエラーがいくつか出ました。make testを管理者権限で実行したためだと判断しました。opcacheのコードの事前ロードではroot権限での実行が禁止されています。ユーザー権限でテストをすると該当のエラーは出ませんでした(代わりroot権限でテストした際には出ないエラーが出ましたが)。

PHPの設定

httpd.confにおけるPHPのLoadModuleのエントリーは--with-apxs2オプションをを付けてビルド・インストールした流れの中で自動的に加わっていると思います。それが出力されているのが確認できたら、.phpの拡張子をもつファイルをPHPとしてパースする設定の記述をします。

httpd.conf はデフォルトでは /usr/local/apache2/conf ディレクトリに存在します。

httpd.conf

...
# 既に存在していると思います
LoadModule php_module         modules/libphp.so
...

<FilesMatch \.php$>
  SetHandler application/x-httpd-php
</FilesMatch>
...

PHPの設定ファイルはソースディレクトリからphp.ini-developmentまたはphp.ini-production、ファイルをコピー・リネームして配置します。デフォルトだと/usr/local/lib/php.iniに配置する決まりになっています。

別環境

環境を、apr-1.7.3、apr-util-1.6.3、httpd-2.4.56にしたところ、libexpat1-devをAPTでインストールした場合、ビルド中に「 undefined reference to `XML_SetElementHandler' 」が発生しました。

なので、libexpatもgitからダウンロードしてビルドします。

追加で git と autoconf 、libtool が必要になります。

# apt install git autoconf
...
# git cline https://github.com/libexpat/libexpat.git
...
# cd libexpat/expat
...
# ./buildconf.sh
...
# ./configure
...
# make
...
# make install
...

一度libexpat-devをインストールしてしまったら、アンインストールし、make install で新しいライブラリを作成した後、ldconfig を実行して再度./configureを実行する必要があると思います。

また、php.ini の配置場所がわかりづらいと思いますが、 php --ini とコマンドを入力することで表示されます。元のソースディレクトリに、php.ini-development(開発用) と php.ini-production(本番用)がありますので、コピーリネームしてベースとします。

インストール後、「 warning: remember to run 'libtool --finish /usr/local/src/php-8.2.4/libs' 」とメッセージが出ると思いますので、指示通り実行しようとすると「 コマンドが見つかりません 」と言われてしまうかもしれません。実行スクリプトの本体が、ビルドを実行したルートに(/usr/local/src) にありますので ./libtool としないといけません。

# ./libtool --finish /usr/local/src/php-8.2.4/libs

PHP8.2

PHP8.2から libmysqlclient での mysqli ビルドが利用できなくなりました。

従来 mysqli ライブラリがベースにするクライアントライブラリには libmysqlclient と mysqlnd の2種類がありました。バージョン5.4からmysqlnd がデフォルトとなっていますが、ビルド時のコンパイルオプションに「 --with-mysqli=/path/to/mysql_config 」とオプションに引数を渡すと libmysqlclient を利用する設定になっています。mysqlnd を使う場合は単に「 --with-mysqli 」としなければなりません。

そのためPHP8.2以降をビルドする際、古い設定「 --with-mysqli=/path/to/mysql_config 」を指定しようとするとエラーになります。

ちなみに、libmysqlclient と mysqlnd の違いですが、libmysqlclient は C言語を念頭に開発されたクライアントライブラリで mysqlnd(NDはNative Driverの略)はPHPを念頭に置いたライブラリです。

PDO や PDO-MySQL,mysqli,mysqlnd,libmysqlclient などのあたり混乱しがちなので整理すると次のようになります。

PHPでMySQLを利用したい場合の拡張ライブラリの選択肢は次の2つです。

  1. PDO MySQL

    PDO(抽象化レイヤー)→PDO MySQL→mysqlnd(低レベルライブラリ)

  2. MySQLi

    mysqli→mysqlnd(低レベルライブラリ)

バージョン8.2以前だと、mysqlnd 以外の低レベルライブラリの選択肢として libmysqlclient が存在します。

詳しくはPHP:「mysqliの概要」を参照してください。

No such file or directory

PHPからMySQLに接続しようとした際に、connectメソッドのあたりで「 No such file or directory 」がでるようなら、php.iniの次の点を確認すると解決するかもしれません。

  • extension_dir の設定

    Debianだったら、extension_dir="./" 部分がコメントアウトになっていないか確認します。(MySQLi使用時)

  • extension の設定

    extension = mysqli のコメントアウトが解除されているかを確認します。(MySQLi使用時)

  • ソケットの場所の指定

    mysqli.default_socket や pdo_mysql.default_socket が MySQL/MariaDB で設定しているソケットの出力場所か確認します。


参考にさせていただきましたサイトの皆様、ありがとうございました。

筆者紹介


自分の写真
がーふぁ、とか、ふぃんてっく、とか世の中すっかりハイテクになってしまいました。プログラムのコーディングに触れることもある筆者ですが、自分の作業は硯と筆で文字をかいているみたいな古臭いものだと思っています。 今やこんな風にブログを書くことすらAIにとって代わられそうなほど技術は進んでいます。 生活やビジネスでPCを活用しようとするとき、そんな第一線の技術と比べてしまうとやる気が失せてしまいがちですが、おいしいお惣菜をネットで注文できる時代でも、手作りの味はすたれていません。 提示されたもの(アプリ)に自分を合わせるのでなく、自分の活動にあったアプリを作る。それがPC活用の基本なんじゃなかと思います。 そんな意見に同調していただける方向けにLinuxのDebianOSをはじめとした基本無料のアプリの使い方を紹介できたらなと考えています。

広告