Toggle navigation
leo's blog
PHP
JavaScript
MySQL
Linux
瞎扯
PHP7扩展开发之"ini配置项读取"
PHP
2020-07-19 15:34:30
30
简介:
php.ini是PHP的主要配置文件,在开发扩展时可以使用配置文件来记录一些整体的控制信息。所在开发扩展过程中就需要读取配置项,读取配置项一般与全局变量配合使用。
此处直接使用全局变量来存储ini文件中的配置信息,如果还不知道如何使用全局变量可以参考 [PHP7扩展开发之"全局变量"](http://phpclub.org.cn/show/34.html "PHP7扩展开发之"全局变量"") #1、设置配置项 在自己的配置文件最后位置中增加配置项为后面读取配置项信息准备 ```ini [phper_leo] phper_leo.version=1 phper_leo.site=https://phpclub.org.cn ``` #2、设置配置项规则 ##实际配置 在phper_leo.c源文件中配置 ```c //配置ini读取 PHP_INI_BEGIN() STD_PHP_INI_ENTRY("phper_leo.version","100",PHP_INI_ALL,OnUpdateLong,global_value,zend_phper_leo_globals,phper_leo_globals) STD_PHP_INI_ENTRY("phper_leo.site","http://baidu.com",PHP_INI_ALL,OnUpdateString,global_string,zend_phper_leo_globals,phper_leo_globals) PHP_INI_END() ``` ##2、原理解释 ### 开始与结束宏 PHP_INI_BEGIN()与PHP_INI_END()为两个实现解析配置的宏,必须成对出现中间用于设置具体每一个配置项的规则 1、PHP_INI_BEGIN宏替换的结果 ``` //main/php.ini.h #define PHP_INI_BEGIN ZEND_INI_BEGIN //zend/zend_ini.h #define ZEND_INI_BEGIN() static const zend_ini_entry_def ini_entries[] = { ``` 2、PHP_INI_END宏替换的结果 ```c //main/php.ini.h #define PHP_INI_END ZEND_INI_END //zend/zend_ini.h #define ZEND_INI_END() { NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0} }; ``` 所以设置配置项的解析也可以直接使用解析结果的变量。推荐使用宏替换 ###配置项规则STD_PHP_INI_ENTRY宏 ```c //main/php.ini.h #define STD_PHP_INI_ENTRY STD_ZEND_INI_ENTRY //zend/zend_ini.h #define STD_ZEND_INI_ENTRY(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) ``` | 参数名称 |含义 | | ------------ | ------------ | | name | php.ini中配置项的名称 | | default_value| 默认值,不论转换后为什么类型这里必须是字符串 | | modifiable | 可以修改的等级,有三个值可以使用分别为:ZEND_INI_USER表示可以在脚本中修改,ZEND_INI_SYSTEM表示可以在php.ini或者httpd.conf中修改,ZEND_INI_ALL表示三组都可以 | | on_modify | 解析函数,当发现name配置项后调用该函数完成解析,也可以自定义,内置有OnUpdateBool、OnUpdateLong、OnUpdateGeZero、OnUpdateReal、OnUpdateString、OnUpdateStringUnempty| | property_name | 要解析到结构体中的成员名称 | | struct_type | 解析到结构体的类型| | struct_ptr | 解析到结构体的指针地址| 其实配置规则是将php.ini中的name配置项的值解析到(struct_type*)struct_ptr上的property_name中,每一个配置项都会生成一个zend_ini_entry_def结构体 zend_ini_entry_def结构体如下 ```c typedef struct _zend_ini_entry_def { const char *name; ZEND_INI_MH((*on_modify)); //映射成员所在结构体的偏移量 void *mh_arg1; //要映射到结构体的地址 void *mh_arg2; void *mh_arg3; const char *value; void (*displayer)(zend_ini_entry *ini_entry, int type); int modifiable; uint name_length; uint value_length; } zend_ini_entry_def; ``` #3、注册规则 上面只是设置了配置项的解析规则,实际要使用还需要注册后才可以得到配置项的值到全局变量中。此时需要在模块初始化阶段上完成配置项的解析即在PHP_MINIT_FUNCTION中使用REGISTER_INI_ENTRIES()即可 ```c PHP_MINIT_FUNCTION(phper_leo) { //解析ini配置项 REGISTER_INI_ENTRIES(); //此宏展开后就是zend_register_ini_entries(ini_entries,module_number) //...其他代码省略 } ``` 在所有的php.ini配置解析完成之后所有的配置项会存储到一个configuration_hash表中,而zend_register_ini_entries的处理就是根据配置的解析规则查看这个hash表,如果找到了则调用on_modify解析函数进行赋值 #4、测试 1、修改所添加的test测试方法 ```c PHP_FUNCTION(test){ // PHPER_LEO_G(global_value) = 30; printf("%d\n",PHPER_LEO_G(global_value)); printf("%s\n",PHPER_LEO_G(global_string)); } ``` 2、重新编译后创建测试文件 ```php <?php test(); ```
Top