龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > php编程 >

php中的ini配置原理详解(5)

时间:2014-10-15 11:15来源:网络整理 作者:网络 点击:
分享到:
char *orig_value; // 配置项的原始值 uint orig_value_length; int orig_modifiable; // 配置项的原始modifiable int modified; // 是否发生过修改,如果有修改,则orig_value会保存修

    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。

精彩图集

赞助商链接