それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

php/php-cliでプロジェクト単位(ディレクトリ単位)の設定を.user.iniで読み込ませる。

php でプロジェクト単位の設定を使いたい

php には、ディレクトリ単位で php の設定を変更する user.ini という特殊なファイルを使うことができる。

イメージとしては .htaccess のようなものでディレクトリに設置することでディレクトリ単位でphpの挙動を変更することが可能。

もし仮に、すべての設定を変更できてしまうと、セキュリティホールを作ったり、php自体の動作を変えてしまえるものなので、すべての変更をできるわけではないが。

php で .user.ini ファイルの使い方

プロジェクトのフォルダに、.user.ini ファイルを置いて 、中身はphp.ini の書き方で設定を上書きする。

これだけ。これでで SAPIの mod_php で使える。php-fcgi のような nginx + php-fpm や apache + php-fpm でもつかえるらしい。

で、コマンドのときはどうするの?

環境変数から指定できます。

たとえば、次のようにすると、カレントディレクトリにある .user.ini を読み込ませる事ができます。

PHP_INI_SCAN_DIR=.  php -i 

これは、bashrc などに記述して export することで別プロセスになっても使用可能です。

export PHP_INI_SCAN_DIR=.

実験してみよう

ここで、環境変数から書き換えを実験してみよう。

.php.user.ini ファイルを作る

date.timezone=UTC

指定して実行する。

takuya@ $ PHP_INI_SCAN_DIR=. php -i | grep timezone
Default timezone => UTC
date.timezone => UTC => UTC

何も指定しないとき

takuya@ $ php -i | grep time
Default timezone => Asia/Tokyo
date.timezone => Asia/Tokyo => Asia/Tokyo

.php.user.ini でいいの?

末尾さえ合ってたら、なんとなく読み込んでくれるんですよね。 conf.d の代わりにも使えそうですね。

takuya@ $ PHP_INI_SCAN_DIR=. php -i | grep ini
Configuration File (php.ini) Path => /usr/local/etc/php/7.3
Loaded Configuration File => /usr/local/etc/php/7.3/php.ini
Scan this dir for additional .ini files => .
Additional .ini files parsed => ./.php.user.ini
user_ini.cache_ttl => 300 => 300
user_ini.filename => .user.ini => .user.ini

PHP_INI_SCAN_DIR=. だけで動かないことも (2023-11-06追記)

PHP_INI_SCAN_DIR=.にすると、/etc/php/xxx/cli/php.ini が読み込まれないことがあるので、ちゃんとバージョンごとに設定する

export PHP_INI_SCAN_DIR=/etc/php/8.2/cli/:/etc/php/8.2/cli/conf.d:.

これめんどくさいんですよねぇ。なんかデフォルトで有効にする事できないのかなぁ。

.user.ini ファイルは便利

このように user.ini ファイルで、一時的な設定を記述することが可能である。

便利に使うと、プロジェクト単位で必要な php.ini の設定を .user.ini として管理できるので、TravisCI のような継続的インテグレーションにおける、自動テスト環境のphp.ini ファイルをいちいち書く必要もないし、Dockerfile でアレコレする必要もなくなる。

とりあえずファイルさえアレば動くというphpの良さが顕在化しているのが user.ini の魅力だと思う。

参考資料

https://stackoverflow.com/questions/41496727/how-to-force-php-cli-to-read-my-user-ini-file