ini ファイルのサポート

PHP 4 では ini ファイルのサポートが設計しなおされています。 デフォルトの初期エントリをコード中で直接指定したり、 それらの値を実行時に読み込んで変更したり、 変更があったことを通知するためのメッセージハンドラを作成したりすることができます。

あなたのモジュール用の .ini セクションを作成するには、 PHP_INI_BEGIN() マクロでセクションの開始位置を指定、 PHP_INI_END() マクロでセクションを終了位置を指定して、 その中に PHP_INI_ENTRY() を使用してエントリを作成します。
PHP_INI_BEGIN()
PHP_INI_ENTRY("first_ini_entry",  "has_string_value", PHP_INI_ALL, NULL)
PHP_INI_ENTRY("second_ini_entry", "2",                PHP_INI_SYSTEM, OnChangeSecond)
PHP_INI_ENTRY("third_ini_entry",  "xyz",              PHP_INI_USER, NULL)
PHP_INI_END()
PHP_INI_ENTRY() マクロは 4 つのパラメータを受け取ります。 パラメータの内容は、それぞれエントリ名、エントリの値、変更の権限、 そして変更通知ハンドラへのポインタとなります。 エントリ名とエントリの値は、たとえ実際の値が整数であったとしても 文字列で指定しなければなりません。

権限は、3 種類に分けられます。 PHP_INI_SYSTEMphp.ini ファイルでしか変更できません。PHP_INI_USER は、実行時にユーザが設定を上書きすることができます。上書きするには .htaccess のような別の設定ファイルを使用します。 そして PHP_INI_ALL の場合は無制限に値を変更することができます。 4 種類目として PHP_INI_PERDIR というものもありますが、 この振る舞いについては検証することができません。 yet.

4 番目のパラメータには、変更通知ハンドラへのポインタを指定します。 これらの ini エントリが変更された際に、ハンドラがコールされます。 ハンドラを宣言するには、PHP_INI_MH マクロを使用します。
PHP_INI_MH(OnChangeSecond);             // ini エントリ "second_ini_entry" 用のハンドラ

// ここで ini エントリを指定します

PHP_INI_MH(OnChangeSecond)
{

    zend_printf("Message caught, our ini entry has been changed to %s<br>", new_value);

    return(SUCCESS);

}
変更ハンドラの変数 new_value に、 新しい値がに文字列として渡されます。 PHP_INI_MH の定義を見ると、 それ以外にもいくつかのパラメータがあることがわかるでしょう。
#define PHP_INI_MH(name) int name(php_ini_entry *entry, char *new_value,
                                  uint new_value_length, void *mh_arg1,
                                  void *mh_arg2, void *mh_arg3)
これらの定義は php_ini.h で確認できます。 メッセージハンドラの内部では、エントリ全体を含む構造体・ 新しい値・その長さ・そして 3 つのオプションの引数にアクセスすることができます。 3 つのオプションの引数を指定するには、 PHP_INI_ENTRY1 (追加の引数を 1 つ指定する)、 PHP_INI_ENTRY2 (追加の引数を 2 つ指定する) そして PHP_INI_ENTRY3 (追加の引数を 3 つ指定する) のそれぞれのマクロを使用します。

変更通知ハンドラを使用すべき場面としては以下のようなものがあります。 高速にアクセスするために ini エントリをローカルにキャッシュしたり、 値が変更された際に何らかのタスクを実行したりといった場合です。 例えば、特定のホストと常に接続を確率している拡張モジュールにおいて ホスト名が変更された場合に、今の接続を自動的に終了させて 新しい接続を確率するなどといったものが考えられます。

表46-17 に示すマクロを使用することによっても、 ini エントリへのアクセスは可能です。

表 46-17. PHP の ini エントリにアクセスするためのマクロ

マクロ説明
INI_INT(name) エントリ name の現在の値を integer (long) で返します。
INI_FLT(name) エントリ name の現在の値を float (double) で返します。
INI_STR(name) エントリ name の現在の値を文字列で返します。 注意: 文字列は複製されず、 内部データへのポインタが返されます。後でこのデータにアクセスするには、 ローカルメモリに複製しなければなりません。
INI_BOOL(name) エントリ name の現在の値を Boolean (zend_bool で定義されるもので、 その実体は、現在は unsigned char) で返します。
INI_ORIG_INT(name) エントリ name の元の値を integer (long) で返します。
INI_ORIG_FLT(name) エントリ name の元の値を float (double) で返します。
INI_ORIG_STR(name) エントリ name の元の値を文字列で返します。 注意: 文字列は複製されず、 内部データへのポインタが返されます。後でこのデータにアクセスするには、 ローカルメモリに複製しなければなりません。
INI_ORIG_BOOL(name) エントリ name の元の値を Boolean (zend_bool で定義されるもので、 その実体は、現在は unsigned char) で返します。

最後に、あなたが作成した ini エントリについて PHP に教えてあげなければなりません。 モジュールのスタートアップ関数およびシャットダウン関数の中で、マクロ REGISTER_INI_ENTRIES() および UNREGISTER_INI_ENTRIES() を使用します。
ZEND_MINIT_FUNCTION(mymodule)
{

    REGISTER_INI_ENTRIES();

}

ZEND_MSHUTDOWN_FUNCTION(mymodule)
{

    UNREGISTER_INI_ENTRIES();

}