【走进php内核】之 运行时配置(conf)

本文深入探讨了PHP内核中的全局变量管理和线程安全资源管理器(TSRM)。在PHP扩展中,全局变量通过ZEND_BEGIN_MODULE_GLOBALS和ZEND_END_MODULE_GLOBALS宏定义,并注册到TSRM。对于php.ini配置,文章解释了其查找路径和简单的语法,并展示了如何在扩展中将配置映射到C语言变量,通过STD_PHP_INI_ENTRY宏设置映射规则,并使用REGISTER_INI_ENTRIES宏执行映射。整个过程分为定义解析规则和执行规则映射两个步骤。
摘要由CSDN通过智能技术生成

全局变量(资源)

使用C语言开发程序时经常会使用全局变量进行数据存储,这就涉及前面已经介绍过的一个问题:线程安全,PHP设计了TSRM(即:线程安全资源管理器)用于解决这个问题,内核中频繁使用到的EG、CG等都是根据是否开启ZTS封装的宏,同样的,在扩展中也需要必须按照TSRM的规范定义全局变量,除非你的扩展不支持多线程的环境。

PHP为扩展的全局变量提供了一种存储方式:每个扩展将自己所有的全局变量统一定义在一个结构体中,然后将这个结构体注册到TSRM中,这样扩展就可以像使用EG、CG那样访问这个结构体。

这个结构体的定义通过ZEND_BEGIN_MODULE_GLOBALS(extension_name)、ZEND_END_MODULE_GLOBALS(extension_name)两个宏完成,这两个宏必须成对出现,中间定义扩展需要的全局变量即可。

ZEND_BEGIN_MODULE_GLOBALS(mytest)
	zend_long	open_cache;
	HashTable	class_table;
ZEND_END_MODULE_GLOBALS(mytest)

展开后实际就是个普通的struct:

typedef struct _zend_mytest_globals {
	zend_long   open_cache;
	HashTable   class_table;
}zend_mytest_globals;

接着创建一个此结构体的全局变量,这时候就会涉及ZTS了,如果未开启线程安全直接创建普通的全局变量即可,如果开启线程安全了则需要向TSRM注册,得到一个唯一的资源id,这个操作也由专门的宏来完成:ZEND_DECLARE_MODULE_GLOBALS(extension_name),展开后:

//ZTS:此时只是定义资源id,并没有向TSRM注册
ts_rsrc_id mytest_globals_id;

//非ZTS
zend_mytest_globals mytest_globals;

最后需要定义一个像EG、CG那样的宏用于访问扩展的全局资源结构体,这一步将使用ZEND_MODULE_GLOBALS_ACCESSOR()宏完成:

#define MYTEST_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(mytest, v)

看起来是不是跟EG、CG的定义非常像?这个宏展开后:

//ZTS
#define MYTEST_G(v) ZEND_TSRMG(mytest_globals_id, zend_mytest_globals *, v)

//非ZTS
#define MYTEST_G(v) (mytest_globals.v)

接下来就可以在扩展中通过:MYTEST_G(opene_cache)、MYTEST_G(class_table)对结构体成员进行读写了。通常会把这个全局资源结构体及结构体的访问宏定义在头文件中,然后把全局变量的声明放到源文件中:

//php_mytest.h
#define MYTEST_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(mytest, v)

ZEND_BEGIN_MODULE_GLOBALS(mytest)
	zend_long   open_cache;
	HashTable   class_table;
ZEND_END_MODULE_GLOBALS(mytest)

//mytest.c
ZEND_DECLARE_
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值