[PHP4BETA] INI entries

From: Date: Sun, 18 Apr 1999 23:34:50 +0000
Subject: [PHP4BETA] INI entries
Groups: php.version4 
Request: Send a blank email to php-version4+get-164@lists.php.net to get a copy of this message
As you would have seen if CVS update email was working earlier, I've worked (and hopefully finalized) the php_ini interface. The code comes to solve several issues: a. The ugly long block of code in main.c that reads values from the cfg_hash into php3_ini. b. Get rid of php3_ini. The performance penalty of copying it around all the time in the Apache module probably wasn't too high, but psychologically, it annoyed me :) c. Get rid of the ugly code in mod_php3.c, that also reads values from Apache directives and puts them into the php3_ini structure. d. Generalize all the code so that you only have to add an entry in one single place and get it automatically supported in php3.ini, Apache, Win32 registry, runtime function ini_get() and ini_alter() and any future method we might have. e. Allow users to easily override *ANY* php3.ini value, except for ones they're not supposed to, of course. I'm happy to say that I think I pretty much reached all goals. php_ini.c implements a mechanism that lets you add your INI entry in a single place, with a default value in case there's no php3.ini value. What you get by using this mechanism: 1. Automatic initialization from php3.ini if available, or from the default value if not. 2. Automatic support in ini_alter(). That means a user can change the value for this INI entry at runtime, without you having to add in a single line of code, and definitely no additional function (for example, in PHP3, we had to add in special dedicated functions, like set_magic_quotes_runtime() or the likes - no need for that anymore). 3. Automatic support in Apache .conf files. 4. No need for a global php3_ini-like variable that'll store all that info. You can directly access each INI entry by name, in runtime. 'Sure, that's not revolutionary, it's just slow' is probably what some of you think - which is true, but, you can also register a callback function that is called each time your INI entry is changed, if you wish to store it in a cached location for intensive use. 5. Ability to access the current active value for a given INI entry, and the 'master' value. Of course, (2) and (3) are only applicable in some cases. Some entries shouldn't be overriden by users in runtime or through Apache .conf files - you can, of course, mark them as such. So, enough hype, how does it work. Essentially: static PHP_INI_MH(OnChangeBar); /* declare a message handler for a change in "bar" */ PHP_INI_BEGIN() PHP_INI_ENTRY("foo", "1", PHP_INI_ALL, NULL, NULL) PHP_INI_ENTRY("bar", "bah", PHP_INI_SYSTEM, OnChangeBar, NULL) PHP_INI_END() static PHP_INI_MH(OnChangeBar) { a_global_var_for_bar = new_value; return SUCCESS; } int whatever_minit(INIT_FUNC_ARGS) { ... REGISTER_INI_ENTRIES(); ... } int whatever_mshutdown(SHUTDOWN_FUNC_ARGS) { ... UNREGISTER_INI_ENTRIES(); ... } and that's it. Here's what it does. As you can probably guess, this code registers two INI entries - "foo" and "bar". They're given defaults "1" and "bah" respectively - note that all defaults are always given as strings. That doesn't reduce your ability to use integer values, simply specify them as strings. "foo" is marked so that it can be changed by anyone at any time (PHP_INI_ALL), whereas "foo" is marked so it can be changed only at startup in the php3.ini only, presumably, by the system administrator (PHP_INI_SYSTEM). When "foo" changes, no function is called. Access to it is done using the macros INI_INT("foo"), INI_FLT("foo") or INI_STR("foo"), which return a long, double or char * respectively (strings that are returned aren't duplicated - if they're manipulated, you must duplicate them first). You can also access the original value (the 'master' value, in case one of them was overriden by a user) using another pair of macros: INI_ORIG_INT("foo"), INI_ORIG_FLT("foo") and INI_ORIG_STR("foo"). When "bar" changes, a special message handler is called, OnBarChange(). Always declare those message handlers using PHP_INI_MH(), as they might change in the future. Message handlers are called as soon as an ini entry initializes or changes, and allow you to cache a certain INI value in a quick C structure. In this example, whenever "bar" changes, the new value is stored in a_global_var_for_bar, which is a global char * pointer, quickly accessible from other functions. Things get a bit more complicated when you want to implement a thread-safe module, but it's doable as well. Message handlers may return SUCCESS to acknowledge the new value, or FAILURE to reject it. That enables you to reject invalid values for some INI entries if you want. Finally, you can have a pointer passed to your message handler - that's the fifth argument to PHP_INI_ENTRY(). It is passed as mh_arg to the message handler. Remember that for certain values, there's really no reason to mess with a callback function. A perfect example for this are the syntax highlight colors, which no longer have a dedicated global C slot that stores them, but instead, are fetched from the php_ini hash on demand. "As always", for a perfect working example of this mechanism, consult functions/mysql.c. This module uses the new INI entry mechanism, and was also converted to be thread safe in general, and in its php_ini support in particular. Converting your modules to look like this for thread safety isn't a bad idea (not necessarily now, but in the long run). I'll work on moving all php3_ini entries to the new mechanism and finally get rid of php3_ini later today or tomorrow. Zeev -- Zeev Suraski <zeev@zend.com> http://www.zend.com/ For a PGP public key, finger bourbon@netvision.net.il -- PHP 4 Beta -- Zeev Suraski <zeev@zend.com> http://www.zend.com/ For a PGP public key, finger bourbon@netvision.net.il -- PHP 4 Beta

« previous php.version4 (#164) next »