php中动态修改ini配置
1,运行时改变配置
在前一篇中曾经谈到,ini_set函数可以在php执行的过程中,动态修改php的部分配置。注意,仅仅是部分,并非所有的配置都可以动态修改。关于ini配置的可修改性,参见:http://php.net/manual/zh/configuration.changes.modes.php
我们直接进入ini_set的实现,函数虽然有点长,但是逻辑很清晰:
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; }
//去EG(ini_directives)中获取配置的值 old_value=zend_ini_string(varname,varname_len+1,0);
/*copytoreturnhere,becausealtermightfreeit!*/ if(old_value){ RETVAL_STRING(old_value,1); }else{ RETVAL_FALSE; }
//如果开启了安全模式,那么如下这些ini配置可能涉及文件操作,需要要辅助检查uid #define_CHECK_PATH(var,var_len,ini)php_ini_check_path(var,var_len,ini,sizeof(ini)) /*safe_mode&basedircheck*/ 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_valueTSRMLS_CC)){ zval_dtor(return_value); RETURN_FALSE; } } }
//在安全模式下,如下这些ini受到保护,不会被动态修改 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; } }
//调用zend_alter_ini_entry_ex去动态修改ini配置 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; } }