php中的ini配置原理详解(5)
char *orig_value; // 配置项的原始值
uint orig_value_length;
int orig_modifiable; // 配置项的原始modifiable
int modified; // 是否发生过修改,如果有修改,则orig_value会保存修改前的值
void (*displayer)(zend_ini_entry *ini_entry, int type);
};
2.3,将配置作用到模块——REGISTER_INI_ENTRIES
经常能够在不同扩展的PHP_MINIT_FUNCTION里看到REGISTER_INI_ENTRIES。REGISTER_INI_ENTRIES主要负责完成两件事情,第一,对模块的全局空间XXX_G进行填充,同步configuration_hash中的值到XXX_G中去。其次,它还生成了EG(ini_directives)。
REGISTER_INI_ENTRIES也是一个宏,展开之后实则为zend_register_ini_entries方法。具体来看下zend_register_ini_entries的实现:
ZEND_API int zend_register_ini_entries(const zend_ini_entry *ini_entry, int module_number TSRMLS_DC) /* {{{ */
{
// ini_entry为zend_ini_entry类型数组,p为数组中每一项的指针
const zend_ini_entry *p = ini_entry;
zend_ini_entry *hashed_ini_entry;
zval default_value;
// EG(ini_directives)就是registered_zend_ini_directives
HashTable *directives = registered_zend_ini_directives;
zend_bool config_directive_success = 0;
// 还记得ini_entry最后一项固定为{ 0, 0, NULL, ... }么
while (p->name) {
config_directive_success = 0;
// 将p指向的zend_ini_entry加入EG(ini_directives)
if (zend_hash_add(directives, p->name, p->name_length, (void*)p, sizeof(zend_ini_entry), (void **) &hashed_ini_entry) == FAILURE) {
zend_unregister_ini_entries(module_number TSRMLS_CC);
return FAILURE;
}
hashed_ini_entry->module_number = module_number;
// 根据name去configuration_hash中查询,取出来的结果放在default_value中
// 注意default_value的值比较原始,一般是数字、字符串、数组等,具体取决于php.ini中的写法
if ((zend_get_configuration_directive(p->name, p->name_length, &default_value)) == SUCCESS) {
// 调用on_modify更新到模块的全局空间XXX_G中
if (!hashed_ini_entry->on_modify || hashed_ini_entry->on_modify(hashed_ini_entry, Z_STRVAL(default_value), Z_STRLEN(default_value), hashed_ini_entry->mh_arg1, hashed_ini_entry->mh_arg2, hashed_ini_entry->mh_arg3, ZEND_INI_STAGE_STARTUP TSRMLS_CC) == SUCCESS) {
hashed_ini_entry->value = Z_STRVAL(default_value);
hashed_ini_entry->value_length = Z_STRLEN(default_value);
config_directive_success = 1;
}
}
// 如果configuration_hash中没有找到,则采用默认值
if (!config_directive_success && hashed_ini_entry->on_modify) {
hashed_ini_entry->on_modify(hashed_ini_entry, hashed_ini_entry->value, hashed_ini_entry->value_length, hashed_ini_entry->mh_arg1, hashed_ini_entry->mh_arg2, hashed_ini_entry->mh_arg3, ZEND_INI_STAGE_STARTUP TSRMLS_CC);
}
p++;
}
return SUCCESS;
}
简单来说,可以把上述代码的逻辑表述为:
1,将模块声明的ini配置项添加到EG(ini_directives)中。注意,ini配置项的值可能在随后被修改。
2,尝试去configuration_hash中寻找各个模块需要的ini。
- 上一篇:php中动态修改ini配置
- 下一篇:9段PHP实用功能的代码推荐