Apache は DocumentRoot に php.ini があればそれを優先する

普段は Docker の公式 PHP イメージ上で開発しているんですけど、 $PHP_INI_DIR/php.ini に設定を記述しても反映されず、いろいろ試した結果 Apache は DocumentRoot に php.ini があればそれを優先する という仕様がありました。

Docker の公式 PHP イメージの php.ini の場所

Docker Hub の Configuration の項にある通り、 php.ini を配置する場所は $PHP_INI_DIR で定義されています。 Dockerfile では下記の通り /usr/local/etc/phpphp.ini を配置する場所として定義しています。

ENV PHP_INI_DIR /usr/local/etc/php

$PHP_INI_DIRphp.ini を配置して、 phpinfo で設定を見てみると、Loaded Configuration File には /usr/local/etc/php/php.ini と表示されます。当然ですね。

DocumentRoot の php.ini が優先して読み込まれる

プロジェクトをデプロイするサーバがレンタルサーバで、 DocumentRoot には本番サーバ用の php.ini を配置する必要がありました。 というわけで、 DocumentRoot に php.ini を配置し、phpinfo で設定を見てみると...

Loaded Configuration File    /var/www/html/php.ini

はい。DocumentRoot の php.ini が読み込まれ、 $PHP_INI_DIR/php.ini は読み込まれなくなりました。

PHP: 設定ファイル - Manualphp.ini の読み込み優先度が記載されていますが、その中にこんな記載があります。

注意:

Apache web サーバーは、スタート時にディレクトリをルート に変更するので、ファイルシステムのルートに php.ini が存在する場合、PHP はそれを読もうとします。

というわけで、つまり DocumentRoot の php.ini を優先して読み込むということみたいです。

共存させるには

Docker の PHP コンテナにも、レンタルサーバへの設定と同じものをあてたい。 かつ開発環境用の設定もしたい。

というわけで、レンタルサーバへの設定として DocumentRoot に php.ini を配置して、 Docker 用の設定は $PHP_INI_DIR/conf.d/php.ini に配置してあげればよいです。

ちなみに

これは ApachePHP を動かしたときの動作なので、DocumentRoot に php.ini が存在していても CLI などで PHP を動かしたときは $PHP_INI_DIR/php.ini が読み込まれます。 php --ini とかするとよくわかります。

root@984f65519eeb:/var/www/html# php --ini
Configuration File (php.ini) Path: /usr/local/etc/php
Loaded Configuration File:         /usr/local/etc/php/php.ini
Scan for additional .ini files in: /usr/local/etc/php/conf.d
Additional .ini files parsed:      /usr/local/etc/php/conf.d/docker-php-ext-gd.ini,
/usr/local/etc/php/conf.d/docker-php-ext-intl.ini,
/usr/local/etc/php/conf.d/docker-php-ext-mysqli.ini,
/usr/local/etc/php/conf.d/docker-php-ext-pdo_mysql.ini,
/usr/local/etc/php/conf.d/docker-php-ext-sodium.ini,
/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini