### 第一步:定义全局变量结构体
扩展的全局变量统一定义在一个结构体中,如下
```c
// php_hello.h
ZEND_BEGIN_MODULE_GLOBALS(hello)
zend_long filter_blank;
ZEND_END_MODULE_GLOBALS(hello)
```
展开后:
```c
typedef struct _zend_hello_globals
{
zend_long filter_blank; // fiter_blank是一个全局变量
} zend_hello_globals;
```
### 第二步:声明全局变量
以上在定义好了结构体,接下来就是要去使用它,声明如下:
```c
// hello.c
ZEND_DECLARE_MODULE_GLOBALS(hello)
```
展开后:
```c
// 开启ZTS(线程安全管理)
ts_rsrc_id module_name##_globals_id;
```
```c
// 没有开启ZTS
zend_hello_globals hello_globals;
```
### 第三步:读写全局变量
php_hello.h定义了HELLO_G(v)宏,可以通过HELLO_G(v)读写全局变量,宏定义如下:
```c
#define HELLO_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(hello, v)
```
展开后:
```c
// ZTS
#define HELLO_G(v) ((zend_hello_globals *)(*((void ***) NULL))((hello_globals_id)-1))->v
```
```c
// 非ZTS
#define HELLO_G(v) hello_globals.v
```
使用如下:
```c
/* {{{ proto int wcl(string filename)
*/
PHP_FUNCTION(wcl)
{
char *filename = NULL;
int argc = ZEND_NUM_ARGS();
size_t filename_len;
char ch, pre = '\n';
FILE *fp;
zend_long lcount = 0;
if (zend_parse_parameters(argc, "s", &filename, &filename_len) == FAILURE)
return;
if ((fp = fopen(filename, "r")) == NULL)
{
RETURN_FALSE;
}
while ((ch = fgetc(fp)) != EOF)
{
if (ch == '\n')
{
if (HELLO_G(filter_blank) && pre == ch) // 读取全局变量filter_blank
{
continue;
}
lcount++;
}
pre = ch;
}
fclose(fp);
RETURN_LONG(lcount);
// php_error(E_WARNING, "wcl: not yet implemented");
}
/* }}} */
```
### php.ini配置
如果我们的程序想通过php.ini程序读取配置,除了需要将配置项定义在全局变量外,还需要将扩展的配置项映射到对应的全局变量,例如php.ini中的hello.filter_blank映射到HELLO_G中的filter_blank全局变量;
比如将php.ini中的hello.filter_blank值映射到HELLO_G()结构中的filter_blank,类型为zend_long,默认值0,则可以这么定义规则:
```c
// hello.c
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("hello.filter_blank", "0", PHP_INI_ALL, OnUpdateLong, filter_blank, zend_hello_globals, hello_globals)
// 其他配置项
PHP_INI_END()
```
以上定义好规则之后,接下来就要进行解析了:
```c
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
PHP_MSHUTDOWN_FUNCTION(hello)
{
/* uncomment this line if you have INI entries
UNREGISTER_INI_ENTRIES(); // 需要把这行注释去掉
*/
UNREGISTER_INI_ENTRIES();
return SUCCESS;
}
/* }}} */
```
- php
- 编译安装
- 基本概念
- 垃圾回收机制
- 生命周期
- zval底层实现
- c扩展开发
- gdb调试工具
- 自定义扩展简单demo
- 钩子函数
- 读取php.ini配置
- 数组
- 函数
- 类
- yaf扩展底层源码
- swoole扩展底层源码
- memoryGlobal内存池
- swoole协程使用记录
- 单点登录sso原理
- compser使用
- session实现机制
- c & linux
- gcc
- 指针
- 结构体,联合和位字段
- 宏定义井号说明
- printf家族函数和可变参数
- 共享函数
- 静态库和动态库
- makefile自动化构建
- 信号一
- 信号二
- inotify监控文件事件
- socket编程
- 简介
- UNIX DOMAIN
- Internet DOMAIN
- TCP/IP
- 文件IO多路复用
- 内存管理
- 进程组,会话和控制终端
- daemon守护进程
- 多进程
- 多线程
- 常用进制转换
- go
- 入门知识
- 字节和整数装换
- python
- redis
- 应用场景
- 消息队列
- 热点数据
- 扫码登录
- 订阅发布
- 次数限制
- 抢购超卖
- 持久化机制
- mysql
- 工作流程
- MyISAM和InnoDB区别
- 用户和权限管理
- 执行计划
- sql优化
- 事务和锁
- 慢查询日志
- case...when...then...end用法
- sql
- 参考
- linux
- 内核参数优化
- 防火墙设置
- docker
- docker入门知识
- 算法
- 多维数组合
- DFA算法
- 红包金额分配