In-depth understanding of INI configuration in PHP (2), in-depth understanding of ini_php tutorials

Source: Internet
Author: User

In-depth understanding of INI configuration in PHP (2), in-depth understanding of INI


Go ahead and write the last one.

1, change configuration at runtime

As mentioned in the previous article, theini_set function can dynamically modify part of PHP's configuration during PHP execution. Note that the only part is that not all configurations can be dynamically modified. For the modification of the INI configuration, see: http://php.net/manual/zh/configuration.changes.modes.php

We go directly to the implementation of Ini_set, which is a bit long, but the logic is clear:

php_function (ini_set) {Char*varname, *New_value; intVarname_len, New_value_len; Char*Old_value; if(Zend_parse_parameters (Zend_num_args () TSRMLS_CC,"SS", &varname, &varname_len, &new_value, &new_value_len) = =FAILURE) {        return; }    //to get the configured value in eg (ini_directives)Old_value = zend_ini_string (varname, Varname_len +1,0); /*Copy to return here, because alter might free it!*/    if(old_value) {retval_string (Old_value,1); } Else{retval_false; }    //If Safe mode is turned on, the following INI configurations may involve file operations and require a secondary check of the UID#define_check_path (Var, var_len, INI) Php_ini_check_path (Var, var_len, INI, sizeof)/*Safe_mode & basedir Check*/    if(PG (safe_mode) | |PG (Open_basedir)) {        if(_check_path (varname, Varname_len,"Error_log") ||_check_path (varname, Varname_len,"Java.class.path") ||_check_path (varname, Varname_len,"Java.home") ||_check_path (varname, Varname_len,"Mail.log") ||_check_path (varname, Varname_len,"Java.library.path") ||_check_path (varname, Varname_len,"vpopmail.directory")) {            if(PG (Safe_mode) && (!Php_checkuid (New_value, NULL, Checkuid_check_file_and_dir)))                {Zval_dtor (return_value);            Return_false; }            if(Php_check_open_basedir (New_value tsrmls_cc)) {zval_dtor (return_value);            Return_false; }        }    }    //in Safe mode, these ini are protected and are not dynamically modified    if(PG (Safe_mode)) {if(!STRNCMP ("Max_execution_time", VarName,sizeof("Max_execution_time")) || !STRNCMP ("Memory_limit", VarName,sizeof("Memory_limit")) || !STRNCMP ("child_terminate", VarName,sizeof("child_terminate")) {zval_dtor (return_value);        Return_false; }    }    //call ZEND_ALTER_INI_ENTRY_EX to dynamically modify the INI configuration    if(ZEND_ALTER_INI_ENTRY_EX (varname, Varname_len +1, New_value, New_value_len, Php_ini_user, Php_ini_stage_runtime,0TSRMLS_CC) = =FAILURE)        {Zval_dtor (return_value);    Return_false; }}

As you can see, in addition to some of the necessary validation work, the main thing is to call ZEND_ALTER_INI_ENTRY_EX.

We continue to follow the ZEND_ALTER_INI_ENTRY_EX function:

Zend_apiint ZEND_ALTER_INI_ENTRY_EX (Char *name,UINT Name_length,Char *new_value,UINT New_value_length,int Modify_type,int stage,int Force_change tsrmls_dc)/*{{{*/{Zend_ini_entry *Ini_entry;char *Duplicate Zend_bool modifiable; Zend_bool modified;//Find the corresponding ini_entry in eg (ini_directives)if (Zend_hash_find (ini_directives), name, Name_length, (void * *) &ini_entry) = =FAILURE) {ReturnFAILURE; }//is modified and modifiable modifiable = ini_entry->modifiable; Modified = ini_entry->Modifiedif (stage = = Zend_ini_stage_activate && Modify_type = =Zend_ini_system) {ini_entry->modifiable =Zend_ini_system; }//Whether to force modificationif (!Force_change) {if (! ( Ini_entry->modifiable &Modify_type)) {ReturnFAILURE; } }//EG (modified_ini_directives) for storing modified Ini_entry
Mainly used for recoveryif (!eg (modified_ini_directives)) {alloc_hashtable (eg (modified_ini_directives)); Zend_hash_init (eg (modified_ini_ directives),8, NULL, NULL,0); }//The value in the Ini_entry, the length of the value, the range can be modified, reserved to Orig_xxx
So that the ini_entry can be restored at the end of the request.
if (!Modified) {Ini_entry->orig_value = ini_entry->Value Ini_entry->orig_value_length = ini_entry->Value_length; Ini_entry->orig_modifiable =modifiable; Ini_entry->modified = 1 ; Zend_hash_add (EG (modified_ini_directives), name, Name_length, &ini_entry, sizeof (zend_ini_ entry* ), NULL); } duplicate = estrndup (new_value, new_value_length); // calls modify to update the corresponding INI configuration in xxx_g if (!ini_entry->on_modify | | ini_entry->on_modify ( Ini_entry, Duplicate, New_value_length, Ini_entry->mh_arg1, Ini_entry->mh_arg2, INI_ENTRY->MH_ARG3, stage TSRMLS_CC) = = SUCCESS) {// same as above, if modified more than once, you need to release the value of the previous modification if (modified && Ini_entry->orig_ Value! = ini_entry->value) { efree (ini_entry-> value);} Ini_entry->value = duplicate; ini_ Entry->value_length = new_value_length;} else {efree (duplicate); return FAILURE; return SUCCESS,

There are 3 logic we need to understand carefully:

1) The Modified field in Ini_entry is used to indicate whether the configuration has been dynamically modified. Once the INI configuration has been modified, the modified will be set to 1. One of the key points in the above code is:

// If you call ini_set more than once, orig_value, and so on, always keep the most primitive values if (! modified) {    ini_entry->orig_value = ini_entry->value;    Ini_entry->orig_value_length = ini_entry->value_length;    Ini_entry->orig_modifiable = modifiable;    Ini_entry1;     sizeof (zend_ini_entry*), NULL);}

This code indicates that no matter how many times we have called Ini_set in PHP code, only the first time Ini_set will enter this logic, set the Orig_value. Starting with the second call to Ini_set, the branch will not be executed again because the modified is now set to 1. Therefore, Ini_entry->orig_value always saves the configuration value before the first modification (that is, the most primitive configuration).

2) The on_modify callback function is required in order for the Ini_set modified configuration to take effect immediately.

As described in the previous article, On_modify is called to be able to update the global variables of the module. Recall again, first of all, the configuration of the module global variable is not a string type, the bool with bool, the use of int with an int. Second, each ini_entry stores the address of the module global variable and the corresponding offset, so that the on_modify can be very quickly memory modification. Also do not forget that after the on_modify call is over, you still need to update the Ini_entry->value further so that the configuration values in the EG (ini_directives) are up to date.

3) A new hash table appears here, EG (modified_ini_directives).

eg (modified_ini_directives) is only used to store the dynamically modified INI configuration, if an INI configuration has been dynamically modified, it exists both in eg (ini_directives) and in eg (modified_ini_ directives). Since every ini_entry has a modified field to mark, wouldn't it be possible to traverse eg (ini_directives) to get all the modified configurations?

The answer is yes. Personally, eg (modified_ini_directives) here is mainly to improve performance, the sauce directly traverse eg (modified_ini_directives) is enough. In addition, deferring the initialization of eg (modified_ini_directives) to ZEND_ALTER_INI_ENTRY_EX, you can also see the performance optimization point of PHP in detail.

2, restore configuration

The action time of the Ini_set and the php.ini file are different, and once the request execution is completed, the Ini_set will fail . In addition, when the ini_restore function is called in our code, the configuration that was previously set by Ini_set is also invalidated.

After each PHP request is executed, Php_request_shutdown is triggered, and Php_request_startup is a two relative process. If PHP is hooked up to Apache/nginx, then every HTTP request is processed, and Php_request_shutdown is called, and if PHP is running in CLI mode, the script will be called after the execution is complete php_request_ Shutdown

In Php_request_shutdown, we can see the recovery processing for INI:

/**/zend_deactivate (Tsrmls_c);

Entering Zend_deactivate, you can further see that the Zend_ini_deactivate function is called, which is the responsibility of the zend_ini_deactivate to restore the PHP configuration.

zend_try {    zend_ini_deactivate (tsrmls_c);} zend_end_try ();

Take a look at the implementation of Zend_ini_deactivate:

int /*  */    {if  (eg (modified_ini_directives))        {//  traverse eg (modified_ini_directives) In this        table //  for each ini_entry call Zend_restore_ini_entry_wrapper         zend_hash_apply (EG (modified_ini_directives), (apply_func_t) Zend_restore_ini_entry_wrapper TSRMLS_CC);                 //  recovery operation         Zend_hash_destroy (EG (modified_ini_directives));        Free_hashtable (EG (modified_ini_directives));         = NULL;    }     return SUCCESS;}

From Zend_hash_apply's point of view, the task of actually recovering INI finally landed on the Zend_restore_ini_entry_wrapper callback function.

Static intZend_restore_ini_entry_wrapper (zend_ini_entry * *ini_entry tsrmls_dc) {    //Zend_restore_ini_entry_wrapper is ZEND_RESTORE_INI_ENTRY_CB's package.ZEND_RESTORE_INI_ENTRY_CB (*ini_entry, Zend_ini_stage_deactivate tsrmls_cc); return 1;}Static intZEND_RESTORE_INI_ENTRY_CB (Zend_ini_entry *ini_entry,intstage TSRMLS_DC) {    intresult =FAILURE; //see only the modified INI entries    if(ini_entry->modified) {        if(ini_entry->on_modify) {            //use Orig_value to reset related fields within the Xxx_gzend_try {result= Ini_entry->on_modify (Ini_entry, Ini_entry->orig_value, Ini_entry->orig_value_length, Ini_entry->mh_ Arg1, INI_ENTRY->MH_ARG2, ini_entry->Mh_arg3, stage tsrmls_cc);        } zend_end_try (); }        if(stage = = Zend_ini_stage_runtime && result = =FAILURE) {            /*runtime failure is OK*/            return 1; }        if(Ini_entry->value! = ini_entry->orig_value) {Efree (Ini_entry-value); }                //Ini_entry itself reverts to the most primitive valueIni_entry->value = ini_entry->Orig_value; Ini_entry->value_length = ini_entry->orig_value_length; Ini_entry->modifiable = ini_entry->orig_modifiable; Ini_entry->modified =0; Ini_entry->orig_value =NULL; Ini_entry->orig_value_length =0; Ini_entry->orig_modifiable =0; }    return 0;}

The logic is quite clear, I believe the reader can see clearly. Summarize the recovery process for INI configuration:

Php_request_shutdown--->zend_deactivate--->zend_ini_deactivate--->zend_restore_ini_entry_wrapper--- >zend_restore_ini_entry_cb

3, configuration of the destruction

At the end of the SAPI life cycle, such as Apache shutdown, CLI program execution, and so on. Once you enter this stage, the previously mentioned Configuration_hash,eg (ini_directives) needs to be destroyed, and the memory space used will need to be freed.

1,php will end all modules in turn, calling Unregister_ini_entries in the php_mshutdown_function of each module. Unregister_ini_entries and Register_ini_entries correspond, but Unregister_ini_entries is not responsible for the release of the module global space, xxx_globals this block is stored in the static data area, No artificial recycling is required.

The main thing unregister_ini_entries do is to remove a module's ini_entry configuration from the eg (ini_directives) table. After deletion, the space of the ini_entry itself is recycled, but the ini_entry->value is not necessarily recycled.

The INI configuration of the core module is only left in EG (ini_directives) after the php_mshutdown_function of all modules has been called unregister_ini_entries once. At this point, you need to manually call Unregister_ini_entries to complete the removal of the core module configuration.

void Php_module_shutdown (tsrmls_d) {    ...         // Zend_shutdown will turn off all PHP modules    except the core // the php_mshutdown_function of each module is called when it is closed     Zend_shutdown (tsrmls_c);        ...     // so far, only the    configuration of the core module is left in EG (ini_directives) // here, clean it up manually .     unregister_ini_entries ();         / /Recycling Configuration_hash     php_shutdown_config ();
    //recycling eg (ini_directives)
Zend_ini_shutdown (Tsrmls_c);
...}

When the manual call to Unregister_ini_entries is complete, eg (ini_directives) already contains no elements, in theory, eg (ini_directives) is an empty hash table.

2,configuration_hash recycling occurs after eg (ini_directives), and the code posted above has a function call about Php_shutdown_config. Php_shutdown_config is mainly responsible for recovering configuration_hash.

int php_shutdown_config (void) {    //  recycle Configuration_hash    Zend _hash_destroy (&configuration_hash);        ...         return SUCCESS;}

Note that Zend_hash_destroy does not release the space of the Configuration_hash itself, as is the case with XXX_G access to the module global space, Configuration_hash is also a global variable, without manual recycling.

3, when the Php_shutdown_config is complete, only eg (ini_directives) of its own space has not been released. So the last step calls Zend_ini_shutdown. The Zend_ini_shutdown is used to release eg (ini_directives). As mentioned earlier, eg (ini_directives) is theoretically an empty hash table, so the space occupied by the hashtable itself needs to be released.

int Zend_ini_shutdown (tsrmls_d) {    //  EG (ini_directives) is a dynamically allocated space that needs to be recycled     Zend_hash_destroy (EG (ini_directives));    Free (EG (ini_directives));     return SUCCESS;}

4, summary

Use a graph to roughly describe the process associated with the INI configuration:


How the INI configuration in PHP is done

Edit the php.ini file directly in the PHP directory to

There is a "register_globals = Off" value, this value is used to open the global variable, such as the value of the form sent over, if the value is set to "Off", you can only use "$_post[' variable name '", $_get[' variable name '] "and so on to get the value sent, if set to "On", you can directly use the "$ variable name" to get the value sent over, of course, set to "Off" is more secure, it will not make it easy to transfer data between pages intercepted. Does this value change to "on" to see oneself feel, is safety important or convenience important?
To use MySQL, it is necessary to "; extension= Php_mysql.dll" before ";" Remove. All the module files are placed under the "ext" of the PHP decompression directory, and the front ";" is used. Just get rid of it.

How PHP reads the INI configuration file and presses it to display

Do you see this in line with your requirements?
';//Traversal All key foreach ($keys [0] as $key) {//If the value is OK and does not exist in the second INI file, the OK if ($values [0][$key]=== ' OK ' and!isset ($values [1][ $key]) {echo ')'; Echo '', $key, ' </td> '; Echo '>

http://www.bkjia.com/PHPjc/893204.html www.bkjia.com true http://www.bkjia.com/PHPjc/893204.html techarticle in-depth understanding of the INI configuration in PHP (2), in-depth understanding INI continues with the previous write. 1, runtime change configuration in the previous article, the Ini_set function can be executed in PHP during the process, ...

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.