如果想在PHP扩展里使用扩展的全局变量,那么最好不要直接定义全局变量。因为PHP 是为多线程设计的,如果直接使用全局变量的话,很可能会读到脏数据。PHP提供了一个创建全局变量的机制,可以同时应用在多线程和非多线程环境中。我们应当始终利用这个机制,而不要自主地定义全局变量。用一个宏访问这些全局变量,使用起来就像普通全局变量一样。在php_yaf.h文件的38到42行就定义了这样一个宏;
#ifdef ZTS
#define YAF_G(v) TSRMG(yaf_globals_id, zend_yaf_globals *, v)
#else
#define YAF_G(v) (yaf_globals.v)
#endif
而php_yaf.h的83到128行就定义了yaf使用到的全局变量:
ZEND_BEGIN_MODULE_GLOBALS(yaf)
/* 这里定义全局变量 */
ZEND_END_MODULE_GLOBALS(yaf)
同时调用:
ZEND_DECLARE_MODULE_GLOBALS(yaf);
使全局变量生效。
而全局变量在每一次创建新的PHP线程时初始化这些全局变量时,这时我们就需要是用 PHP_GINIT_FUNCTION 宏来定义和注册这样一个构造函数了。
PHP_GINIT_FUNCTION 实际上对应到 ZEND_GINIT_FUNCTION,而 ZEND_GINIT_FUNCTION 实际上是 ZEND_MODULE_GLOBALS_CTOR_D;
PHP_GINIT_FUNCTION(yaf)
{
/** 初始化全局变量 */
}
实际会生成以下C代码:
void zm_globals_ctor_yaf (zend_yaf_globals *yaf_globals TSRMLS_DC)
{
/** 初始化全局变量 */
}
在线程退出时,需要将之前自己申请的资源释放时,可以使用 PHP_GSHUTDOWN_FUNCTION来注册析构函数。
PHP_GSHUTDOWN_FUNCTION(yaf)
{
/** 清除全局变量 */
}
实际生成以下C代码:
void zm_globals_dtor_yaf (zend_yaf_globals *yaf_globals TSRMLS_DC)
{
/** 清除全局变量 */
}