画像の縮小や形式の変換に、PHP の拡張機能 Imagick を使うことがあります。Imagick は、画像処理のソフトウェア ImageMagick を PHP から使うためのものです。Windows の XAMPP のような手元の開発環境に入れようとして php.ini に extension=imagick を書き足したところ、Apache が起動しなくなった、ページを開いた瞬間に Apache ごと落ちた、ということがよく起こります。多くの場合、原因は、拡張機能と環境の組み合わせが合っていないことです。

なぜ Apache ごと落ちるのか

XAMPP では、PHP は Apache のモジュールとして、Apache のプロセスの中で動いています。PHP の拡張機能 (Windows では DLL というファイル) も、同じプロセスに読み込まれます。合わない DLL を読み込むと、PHP のエラーでは済まず、Apache のプロセスそのものが異常終了することがあります。そのため、PHP のエラーメッセージが何も出ないまま、Apache が止まったように見えます。

合わせる必要がある組み合わせ

Windows 向けの PHP の拡張機能は、次の組み合わせごとに別々のファイルとして作られています。1 つでも違うと、読み込めないか、正しく動きません。

  • PHP の版: 8.2 用、8.3 用のように、小数点以下の数字の版ごとに分かれる
  • スレッドセーフ (TS) か、そうでない (NTS) か: Apache のモジュールとして動かす PHP は TS。FastCGI で動かす PHP は NTS が一般的
  • 32 ビット (x86) か、64 ビット (x64) か
  • ビルドに使ったコンパイラー: Visual C++ の版で、VS16 や VS17 のように表す
  • ImageMagick 本体の DLL: Imagick の DLL は、ビルドに使われた ImageMagick の DLL を必要とする。別に入れた ImageMagick と版や種類が違うと、読み込みに失敗することがある

ImageMagick の DLL が見つからない (PATH の通った場所に無い) ときも、拡張機能は読み込めません。とはいえ、DLL を Windows のシステムのフォルダーに手当たり次第にコピーするのは避けます。ほかのソフトウェアに影響したり、あとで何を入れたのかわからなくなったりします。

phpinfo() で確かめる項目

DLL を探す前に、今の PHP がどの組み合わせなのかを phpinfo() で確かめます。

<?php
// 確かめ終わったら、必ず削除する (公開するサーバーに置いたままにしない)
phpinfo();

見るのは、次の項目です。

  • PHP Version: PHP の版
  • Architecture: x64 か x86 か
  • Thread Safety: enabled なら TS、disabled なら NTS
  • Compiler: ビルドに使ったコンパイラー
  • PHP Extension Build: API20220829,TS,VS16 のように、拡張機能を選ぶのに必要な値がまとめて書かれている
  • Loaded Configuration File: 読み込まれている php.ini の場所 (書き換えたファイルが合っているか)
  • extension_dir: 拡張機能の DLL を置くフォルダー

コマンドラインの PHP でも確かめられます。ただし、コマンドラインの PHP は Apache の PHP と別の php.ini を読んでいることがあるので、拡張機能が読み込まれたかどうかは、両方で見ます。

# 版、TS かどうか (ZTS と表示される)、コンパイラー、ビット数を表示する
php -v
# Imagick が読み込まれていれば、その版などを表示する
php --ri imagick

落ちたときの戻し方と調べ方

まず、追加した行を無効にして、Apache が起動する状態に戻します。php.ini では、行の先頭に ; を付けるとコメントになります。

; いったん無効にして、Apache が起動するか確かめる
;extension=imagick

そのうえで、次の順に調べます。

  1. Apache のエラーログ (XAMPP なら apache\logs\error.log) と、PHP のエラーログを見る
  2. Windows のイベントビューアーの「Windows ログ」→「アプリケーション」を見る。httpd.exe の異常終了と、原因になったモジュール (DLL) の名前が記録されていることがある
  3. phpinfo() で確かめた組み合わせと、入れた DLL の組み合わせを見比べる

今は、本番と同じ環境を用意するのが楽

組み合わせをそろえて動いたとしても、手元の Windows と本番のサーバー (多くは Linux) では、ImageMagick の版や対応する画像の形式が違い、仕上がりが変わることがあります。今は、Docker などで本番と同じ PHP の版の環境を用意し、その中に拡張機能を入れるのが楽です。Windows でも、WSL2 を使えば Linux の環境で動かせます。

Docker の公式の PHP のイメージなら、Linux のパッケージと PECL (PHP の拡張機能の配布の仕組み) で Imagick を入れられます。

# 本番と同じ PHP の版を指定する
FROM php:8.3-apache

# ImageMagick の開発用のパッケージを入れてから、Imagick をビルドして有効にする
RUN apt-get update \
 && apt-get install -y --no-install-recommends libmagickwand-dev \
 && pecl install imagick \
 && docker-php-ext-enable imagick \
 && rm -rf /var/lib/apt/lists/*

本番のレンタルサーバーで Imagick が使えるか、どの版の ImageMagick が入っているかも、サーバー上の phpinfo() で確かめておきます。縮小や切り抜き程度なら、多くの環境で最初から使える GD という拡張機能で足りることもあります。

まとめ

  • PHP は Apache のプロセスの中で動くため、合わない拡張機能を読み込むと Apache ごと落ちることがある
  • PHP の版、TS か NTS か、x86 か x64 か、コンパイラー、ImageMagick の DLL の組み合わせをそろえる
  • 組み合わせは phpinfo() の Thread Safety、Architecture、PHP Extension Build などで確かめる
  • 落ちたら、まず extension=imagick を無効にして戻し、ログとイベントビューアーを見る
  • 今は、Docker などで本番と同じ環境を作り、その中で拡張機能を入れるのが楽

参考