struct _zend_ini_entry {
int module_number; // 模块的id
int modifiable; // 可被修改的范围,例如php.ini,ini_set
char *name; // 配置项的名称
uint name_length;
ZEND_INI_MH((*on_modify)); // 回调函数,配置项注册或修改的时候会调用
void *mh_arg1; // 通常为配置项字段在XXX_G中的偏移量
void *mh_arg2; // 通常为XXX_G
void *mh_arg3; // 通常为保留字段,极少用到
char *value; // 配置项的值
uint value_length;
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;
}
}