Toggle navigation
leo's blog
PHP
JavaScript
MySQL
Linux
瞎扯
PHP7扩展开发之"全局变量"
PHP
2020-07-19 13:53:42
39
简介:
在使用C语言开发扩展时经常会使用到全局变量进行数据的存储,以实现函数间的数据共享,例如读取php.ini配置信息后多个函数的使用此时就可以使用全局变量
如果在扩展中需要使用全局变量来实现数据共享,可以像内核中的EG、CG这样像TSRM注册全局资源。首先定义一个保存全局变量的结构体,然后再讲结构体注册到TSRM中 #1、申明全局变量结构体 此步骤是在扩展的头文件中定义(本例文件为 php_phper_leo.h) 1、申明全局变量结构体 涉及到ZEND_BEGIN_MODULE_GLOBALS与ZEND_END_MODULE_GLOBALS两个宏,这两个宏必须成对的出现分别表示开始与结束。例如: ```c ZEND_BEGIN_MODULE_GLOBALS(phper_leo) zend_long global_value;//结构体下的变量 global_value char *global_string;//结构体变量 global_string ZEND_END_MODULE_GLOBALS(phper_leo) ``` 其中phper_leo表示设置全局变量的名称,展开后的实际结构体为 ```c typedef struct _zend_phper_leo_globals{ zend_long global_value; char *global_string; }zend_phper_leo_globals ``` 2、注册全局变量结构体 此处涉及到ZTS线程安全问题,如果未开启线程安全则直接创建普通全局变量,如果开启了线程安全则需要像TSRM注册得到资源的唯一标识。此操作是由ZEND_MODULE_GLOBALS_ACCESSOR(name)宏完成 ```c #define PHPER_LEO_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(phper_leo, v) #if defined(ZTS) && defined(COMPILE_DL_PHPER_LEO) ZEND_TSRMLS_CACHE_EXTERN() #endif ``` PHPER_LEO_G自定义的一个宏名称,后面在源码中需要使用此名称的宏来进行全局变量的访问 #2、使用全局变量 此处操作的文件为扩展源码文件(phper_leo.c) 1、使用全局变量 ```c ZEND_DECLARE_MODULE_GLOBALS(phper_leo) ``` 2、创建2个用于测试的函数 ```c //初始化全局变量中的global_value为30 PHP_FUNCTION(test){ //操作全局变量结构体下的global_value的值 PHPER_LEO_G(global_value) = 30; printf("%d\n",PHPER_LEO_G(global_value)); } //设置全局变量中global_value加1 PHP_FUNCTION(test2){ PHPER_LEO_G(global_value) ++; printf("%d\n",PHPER_LEO_G(global_value)); } ``` 3、将创建的2个测试函数注册到扩展函数中 ```c //自定义扩展所提供的函数 const zend_function_entry phper_leo_functions[] = { PHP_FE(confirm_phper_leo_compiled, NULL) /* For testing, remove later. */ PHP_FE(get_total,NULL) //添加的测试函数 PHP_FE(test,NULL) PHP_FE(test2,NULL) PHP_FE_END /* Must be the last line in phper_leo_functions[] */ }; ``` 4、重新编译后创建测试php ```php <?php test(); //30 test2();//31 ```
Top