Programming PHPProgramming PHPSearch this book

14.12. Extension INI Entries

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:

PHP_INI_BEGIN( )
    STD_PHP_INI_ENTRY("foo.my_ini_setting", "0", PHP_INI_ALL, OnUpdateInt, 
                      setting, zend_foo_globals, foo_globals)
PHP_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:

OnUpdateBool
OnUpdateInt
OnUpdateReal
OnUpdateString
OnUpdateStringUnempty

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:

static PHP_INI_MH(MyUpdateSetting) {
    int val = atoi(new_value);
    if(val>10) {
        return FAILURE;
    }
    FOO_G(value) = val;
    return SUCCESS;
}

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:

#define PHP_INI_MH(name) int name(zend_ini_entry *entry, char *new_value, \
                                  uint new_value_length, void *mh_arg1, \
                                  void *mh_arg2, void *mh_arg3, int stage \ 
                                  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.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.