5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
;
{
short size;
int ;
char ;
char zts;
const*;
const*deps;
const char *name;
const*;
int (*)();
int (*)();
int (*)();
int (*c)();
void (*)();
const char *;
;
#ifdef ZTS
* ;
#else
void * ;
#endif
void (*)( void * );
void (*)( void * );
int (*)( void );
int ;
char type;
void *;
int ;
char *;
};
这个结构体可能看起来会让人有点头疼,不过我还是要解释一下里面的内容 。因为这就是PHP 的原型,如果不搞清楚,就没法开发PHP 了 。当然,我就不一一对每个字段进行解释了,只拣关键的、这篇文章会用到的字段说,因为许多字段并不需要我们手工填写,而是可以使用某些预定义的宏填充 。
第7个字段“name”,这个字段是此PHP 的名字,在本例中就是“” 。
第8个字段“”,这个将存放我们在此扩展中定义的函数的引用,具体结构不再分析,有兴趣的朋友可以阅读的源代码 。具体编写代码时这里会有相应的宏 。
第9-12个字段分别是四个函数指针,这四个函数会在相应时机被调用,分别是“扩展模块加载时”、“扩展模块卸载时”、“每个请求开始时”和“每个请求结束时” 。这四个函数可以看成是一种拦截机制,主要用于相应时机的资源分配、释放等相关操作 。
第13个字段“”也是一个函数指针,这个指针指向的函数会在执行()时被调用,用于显示自定义模块信息 。
第14个字段“”是模块的版本 。
(关于更详尽的介绍请参考这里)
介绍完以上字段,我们可以看看“.c”中自动生成的“ry”框架代码了 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* {{{ ry
*/
ry = {
#if>=
ER,
#endif
"" ,
,
(),
(),
(),/*with NULL if there'sto do atstart */
(),/*with NULL if there'sto do atend */
(),
#if>=
"0.1" ,/*withfor your*/
#endif
};
/* }}} */
首先,宏“ER”会生成前6个字段,“ ”会生成“”后的字段,所以现在我们还不用操心 。而我们关心的几个字段,也都填写好或由宏生成好了,并且在“.c”的相应位置也生成了几个函数的框架 。这里要注意,几个宏的参数均为“”,但这并不表示几个函数的名字全为“”,C语言中也不可能存在函数名重载机制 。实际上,在开发PHP 的过程中,几乎处处都要用到Zend里预定义的各种宏,从全局变量到函数的定义甚至返回值,都不能按照“裸写”的方式来编写C语言,这是因为PHP的运行机制可能会导致命名冲突等问题,而这些宏会将函数等元素变换成一个内部名称,但这些对程序员都是透明的(除非你去阅读那些宏的代码),我们通过各种宏进行编程,而宏则为我们处理很多内部的东西 。
写到这里,我们的任务就明了了:第一,如果需要在相应时机处理一些东西,那么需要填充各个拦截函数内容;第二,编写的功能函数,并将引用添加到中 。
编写()回调函数
因为扩展在各个生命周期阶段并不需要做操作,所以我们只编写的内容,上文说过,这个函数将在()执行时被自动调用,用于显示扩展的信息 。编写这个函数会用到四个函数: