php中的ini配置原理详解(6)
如果能够找到,说明用户叜ini文件中配置了该值,那么采用用户的配置。
如果没有找到,OK,没有关系,因为模块在声明ini的时候,会带上默认值。
3,将ini的值同步到XX_G里面。毕竟在php的执行过程中,起作用的还是这些XXX_globals。具体的过程是调用每条ini配置对应的on_modify方法完成,on_modify由模块在声明ini的时候进行指定。
我们来具体看下on_modify,它其实是一个函数指针,来看两个具体的Core模块的配置声明:
STD_PHP_INI_BOOLEAN("log_errors", "0", PHP_INI_ALL, OnUpdateBool, log_errors, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("log_errors_max_len","1024", PHP_INI_ALL, OnUpdateLong, log_errors_max_len, php_core_globals, core_globals)
对于log_errors,它的on_modify被设置为OnUpdateBool,对于log_errors_max_len,则on_modify被设置为OnUpdateLong。
进一步假设我们在php.ini中的配置为:
log_errors = On
log_errors_max_len = 1024
具体来看下OnUpdateBool函数:
ZEND_API ZEND_INI_MH(OnUpdateBool)
{
zend_bool *p;
// base表示core_globals的地址
char *base = (char *) mh_arg2;
// p表示core_globals的地址加上log_errors字段的偏移量
// 得到的即为log_errors字段的地址
p = (zend_bool *) (base+(size_t) mh_arg1);
if (new_value_length == 2 && strcasecmp("on", new_value) == 0) {
*p = (zend_bool) 1;
}
else if (new_value_length == 3 && strcasecmp("yes", new_value) == 0) {
*p = (zend_bool) 1;
}
else if (new_value_length == 4 && strcasecmp("true", new_value) == 0) {
*p = (zend_bool) 1;
}
else {
// configuration_hash中存放的value是字符串"1",而非"On"
// 因此这里用atoi转化成数字1
*p = (zend_bool) atoi(new_value);
}
return SUCCESS;
}
最令人费解的估计就是mh_arg1和mh_arg2了,其实对照前面所述的zend_ini_entry定义,mh_arg1,mh_arg2还是很容易参透的。mh_arg1表示字节偏移量,mh_arg2表示XXX_globals的地址。因此,(char *)mh_arg2 + mh_arg1的结果即为XXX_globals中某个字段的地址。具体到本case中,就是计算core_globals中log_errors的地址。因此,当OnUpdateBool最后执行到
*p = (zend_bool) atoi(new_value);
其作用就相当于
core_globals.log_errors = (zend_bool) atoi("1");
分析完了OnUpdateBool,我们再来看OnUpdateLong便觉得一目了然:
- 上一篇:php中动态修改ini配置
- 下一篇:9段PHP实用功能的代码推荐