ZTS 版の PHP に PECL 拡張モジュールをインストールする
PHP に PECL 拡張モジュールをインストールしようとしてハマったのでメモ。
PHP で ImageMagick を使うためのラッパーであるimagick(pecl.php.net
)のインストールを例にします。
pecl install
でインストール
まずは普通にインストールしてみます。 ImageMagick については、 yum install ImageMagick
だと古いバージョン6系がインストールされてしまうので、公式サイトのダウンロードページ(imagemagick.org
)から7系最新バージョンの RPM ファイルを直接指定してインストール。
yum install https://imagemagick.org/download/linux/CentOS/x86_64/ImageMagick-libs-7.0.10-29.x86_64.rpm
yum install https://imagemagick.org/download/linux/CentOS/x86_64/ImageMagick-7.0.10-29.x86_64.rpm
yum install https://imagemagick.org/download/linux/CentOS/x86_64/ImageMagick-devel-7.0.10-29.x86_64.rpm
続いて PECL で imagick をインストールします。
- これは ZTS 版の PHP ではダメな例であり、後でアンインストールする羽目になります。失敗の経験も含めて書き残しておく次第です。
pecl install imagick
インストールが完了するとこうなります。
このメッセージでとくに重要なのは以下の2点です。
- モジュールディレクトリ(
/usr/lib64/php/modules/
)に imagick.so がインストールされた - php.ini に
extension=imagick.so
の記述を手動で追加せよ
メッセージどおり php.ini に追記してもいいのですが、他のモジュールと同じように個別の .ini ファイルを作って .so を読み込むようにします。
vi /etc/php.d/20-imagick.ini
ファイルの中身はこれだけ。
extension=imagick
-
インストールのメッセージでは前述のとおり
extension=imagick.so
と書くように指示されていますが、これは古い書き方です。公式マニュアルにはPHP 7.2.0 以降では、拡張機能の名前が、拡張機能のファイル名の代わりに使えるようになりました。 これは OS に依存せず、特に初心者に簡単な仕組みです。 これは、読み込む拡張機能を指定する推奨できるやり方になっています。
(www.php.net
)とあるので、拡張子なしの記述の方が良いでしょう。こうすることで開発機は Windows 、本番環境は Linux といった場合でも記述を統一できるメリットがあります。
php -m
してみると、ちゃんと imagick も追加されています。
Web 画面の phpinfo()
で認識されない
ところが、 Web 画面で phpinfo()
を見ると imagick は追加されていません。よく見るとScan this dir for additional .ini files
のディレクトリが /etc/php-zts.d
となっています。また extension_dir
も /usr/lib64/php-zts/modules
です。
この zts
とは何なのかいろいろ調べてみたところ、以前サイトを HTTP/2 対応した際、 Apache の動作を prefork
→ event
に変更したことが原因だと分かりました。 Apache + PHP の組み合わせでは、 Apache が prefork
モードでない場合、 Zend Thread Safety(ZTS)版の PHP が読み込まれるようになるようです。これは Apache の設定ファイル(私の環境だと /etc/httpd/conf.modules.d/15-php.conf
)に書かれています。
#
# PHP is an HTML-embedded scripting language which attempts to make it
# easy for developers to write dynamically generated webpages.
#
# Cannot load both php5 and php7 modules
<IfModule !mod_php5.c>
<IfModule prefork.c>
LoadModule php7_module modules/libphp7.so
</IfModule>
</IfModule>
<IfModule !mod_php5.c>
<IfModule !prefork.c>
LoadModule php7_module modules/libphp7-zts.so
</IfModule>
</IfModule>
つまり、先ほど実施した pecl install
では非 ZTS 版の方にインストールされてしまったので、 php コマンドを叩くと認識されるものの、 Web の PHP にはインストールされていないということだったのです。 ZTS 版の PHP の実態は /usr/bin/zts-php
にあるので、 php -m
でなく zts-php -m
をすると、やはり imagick は追加されていませんでした。
ZTS 版の PHP に PECL 拡張モジュールをインストール
で本題ですが、 pecl install
に ZTS 版へインストールするオプションがあれば一発解決なのですが、どうやらそのようなものはなさそうです(この辺あまり詳しくないので、もしあったら教えてください)。
なので手動ビルドすることにします。 PECL の imagick のページ(pecl.php.net
)へ行き、最新バージョン(2020年9月9日現在は 3.4.4)の URL を調べて落とします。
wget https://pecl.php.net/get/imagick-3.4.4.tgz
gunzip imagick-3.4.4.tgz
tar -xvf imagick-3.4.4.tar
あとは公式マニュアルの phpize で共有 PECL 拡張モジュールをコンパイルする方法(www.php.net
)を参考にしますが、下記2点に注意です。
phpize
の代わりにzts-phpize
を使う./configure
のオプションで ZTS 版のphp-config
を指定する
cd imagick-3.4.4
zts-phpize
./configure --with-php-config=/usr/bin/zts-php-config
make
sudo make install
あとは先ほどと同じ要領で設定ファイルに extension=imagick
を記述します。
vi /etc/php-zts.d/20-imagick.ini
サーバーを再起動すると、 Web 版の phpinfo()
にも imagick が追加されました。
最後に、非 ZTS 環境にインストールしてしまった imagick をアンインストールします。
pecl uninstall imagick
rm /etc/php.d/20-imagick.ini