高级编程:PHP扩展的 INI 配置文件操作

Posted by LB on Thu, Nov 22, 2018

Extension INI Entries (扩展INI配置项)

Defining php.ini directives (i.e., INI entries) in an extension is easy. Most of the work involves setting up the global struct explained earlier in Section 14.10.3 Each entry in the INI structure is a global variable in the extension and thus has an entry in the global struct and is accessed using FOO_G(my_ini_setting). For the most part you can simply comment out the indicated sections in the skeleton created by ext_skel to get a working INI directive, but we will walk through it here anyway.

To add a custom INI entry to your extension, define it in your main foo.c file using:

1PHP_INI_BEGIN( )
2STD_PHP_INI_ENTRY("foo.my_ini_setting", "0", PHP_INI_ALL, OnUpdateInt, 
3setting, zend_foo_globals, foo_globals)
4PHP_INI_END( )

The arguments to the STD_PHP_INI_ENTRY( ) macro are: entry name, default entry value, change permissions, pointer to change modification handler, corresponding global variable, global struct type, and global struct. The entry name and default entry value should be self-explanatory. The change permissions parameter specifies where this directive can be changed. The valid options are:

PHP_INI_SYSTEM

The directive can be changed in php.ini or in httpd.conf using the php_admin_flag/php_admin_value directives.

PHP_INI_PERDIR

The directive can be changed in httpd.conf or .htaccess (if AllowOverride OPTIONS is set) using the php_flag/php_value directives.

PHP_INI_USER

The user can change the directive using the ini_set( ) function in scripts.

PHP_INI_ALL

A shortcut that means that the directive can be changed anywhere.

The change modification handler is a pointer to a function that will be called when the directive is modified. For the most part, you will probably use one of the built-in change-handling functions here.

The functions available to you are:

1OnUpdateBool
2OnUpdateInt
3OnUpdateReal
4OnUpdateString
5OnUpdateStringUnempty

However, there may be cases where you want to check the contents of an INI setting for validity before letting it be set, or there may be things you need to call to initialize or reconfigure when one of these settings is changed. In those cases, you will have to write your own change-handling function.

When you have a custom change handler, you use a simpler INI definition. In place of STD_PHP_INI_ENTRY( ), as shown previously, use:

PHP_INI_ENTRY(“foo.my_ini_setting”, “0”, PHP_INI_ALL, MyUpdateSetting)

The MyUpdateSetting( ) function can then be defined like this:

1static PHP_INI_MH(MyUpdateSetting) {
2     int val = atoi(new_value);
3     if(val>10) {
4         return FAILURE;
5     }
6     FOO_G(value) = val;
7     return SUCCESS;
8 }

As you can see, the new setting is accessed via the char *new_value. Even for an integer, as in our example, you always get a char *. The full PHP_INI_MH( ) prototype macro looks like this:

1#define PHP_INI_MH(name) int name(zend_ini_entry *entry, char *new_value, \
2                                  uint new_value_length, void *mh_arg1, \
3                                   void *mh_arg2, void *mh_arg3, int stage \ 
4                                   TSRMLS_DC)

The extra mh_arg1, mh_arg2, and mh_arg3 are custom user-defined arguments that you can optionally provide in the INI_ENTRY section. Instead of using PHP_INI_ENTRY( ) to define an INI entry, use PHP_INI_ENTRY1( ) to provide one extra argument, PHP_INI_ENTRY2( ) for two, and PHP_INI_ENTRY3( ) for three.

Next, after either using the built-in change handlers or creating your own, find the PHP_MINIT_FUNCTION( ) and add this after the ZEND_INIT_MODULE_GLOBALS( ) call:

REGISTER_INI_ENTRIES( );

In the PHP_MSHUTDOWN_FUNCTION( ), add:

UNREGISTER_INI_ENTRIES( );

In the PHP_MINFO_FUNCTION( ), you can add:

DISPLAY_INI_ENTRIES( );

This will show all the INI entries and their current settings on the phpinfo( ) page.

原文链接:https://docstore.mik.ua/orelly/webprog/php/ch14_12.htm