### 第一步:定義全局變量結構體
擴展的全局變量統一定義在一個結構體中,如下
```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算法
- 紅包金額分配