下面列出自己的实战步骤,主要涉及到这3个文件:
config.m4:这是Unix环境下的Build System配置文件,后面将会通过它生成配置和安装。
php_say_hello.h:这是扩展模块的头文件。这个里面可以放置一些自定义的结构体、全局变量等等。
say_hello.c:这是扩展模块的主程序文件,最终的扩展模块各个函数入口都在这里。
qiqi@qiqi-virtual-machine:~/php-5.3.23/ext$ ./ext_skel --extname=say_hello
Creating directory say_hello
Creating basic files: config.m4 config.w32 .svnignore say_hello.c php_say_hello.h CREDITS EXPERIMENTAL tests/001.phpt say_hello.php [done].
To use your new extension, you will have to execute the following steps:
1. $ cd ..
2. $ vi ext/say_hello/config.m4
3. $ ./buildconf
4. $ ./configure --[with|enable]-say_hello
5. $ make
6. $ ./php -f ext/say_hello/say_hello.php
7. $ vi ext/say_hello/say_hello.c
8. $ make
Repeat steps 3-6 until you are satisfied with ext/say_hello/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.
qiqi@qiqi-virtual-machine:~/php-5.3.23/ext$ ls say_hello
config.m4 config.w32 CREDITS EXPERIMENTAL php_say_hello.h say_hello.c say_hello.php tests
qiqi@qiqi-virtual-machine:~/php-5.3.23/ext$ vim say_hello/config.m4
把文件中这三行的dnl删掉,打开注释。
dnl PHP_ARG_ENABLE(say_hello, whether to enable say_hello support,
dnl Make sure that the comment is aligned:
dnl [ --enable-say_hello Enable say_hello support])
qiqi@qiqi-virtual-machine:~/php-5.3.23/ext/say_hello$ vim say_hello/php_say_hello.h
extern zend_module_entry say_hello_module_entry;
其中zend_module_entry 的结构定义如下,写在Zend/zend_modules.h中,或者参考http://www.php.net/manual/en/internals2.structure.modstruct.php
typedef struct _zend_module_entry zend_module_entry;
struct _zend_module_entry {
unsigned short size;
unsigned int zend_api;
unsigned char zend_debug;
unsigned char zts;
const struct _zend_ini_entry *ini_entry;
const struct _zend_module_dep *deps;
const char *name;
const struct _zend_function_entry *functions;
int (*module_startup_func)(INIT_FUNC_ARGS);
int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
int (*request_startup_func)(INIT_FUNC_ARGS);
int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);
void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);
const char *version;
size_t globals_size;
#ifdef ZTS
ts_rsrc_id* globals_id_ptr;
#else
void* globals_ptr;
#endif
void (*globals_ctor)(void *global TSRMLS_DC);
void (*globals_dtor)(void *global TSRMLS_DC);
int (*post_deactivate_func)(void);
int module_started;
unsigned char type;
void *handle;
int module_number;
char *build_id;
};
第7个字段“name”,这个字段是此PHP Extension的名字,在本例中就是“say_hello”。
第8个字段“functions”,这个将存放我们在此扩展中定义的函数的引用,具体结构不再分析,有兴趣的朋友可以阅读_zend_function_entry的源代码。具体编写代码时这里会有相应的宏。
第9-12个字段分别是四个函数指针,这四个函数会在相应时机被调用,分别是“扩展模块加载时”、“扩展模块卸载时”、“每个请求开始时”和“每个请求结束时”。这四个函数可以看成是一种拦截机制,主要用于相应时机的资源分配、释放等相关操作。
第13个字段“info_func”也是一个函数指针,这个指针指向的函数会在执行phpinfo()时被调用,用于显示自定义模块信息。
第14个字段“version”是模块的版本。
在say_hello.c里编写phpinfo()回调函数 :
因为say_hello扩展在各个生命周期阶段并不需要做操作,所以我们只编写info_func的内容,上文说过,这个函数将在phpinfo()执行时被自动调用,用于显示扩展的信息。编写这个函数会用到四个函数:
php_info_print_table_start()——开始phpinfo表格。无参数。
php_info_print_table_header()——输出表格头。第一个参数是整形,指明头的列数,然后后面的参数是与列数等量的(char*)类型参数用于指定显示的文字。
php_info_print_table_row()——输出表格内容。第一个参数是整形,指明这一行的列数,然后后面的参数是与列数等量的(char*)类型参数用于指定显示的文字。
php_info_print_table_end()——结束phpinfo表格。无参数。
在say_hello.c中加入say_hello的主函数:
/* True global resources - no need for thread safety here */
static int le_say_hello;
/* {{{ PHP_FUNCTION
*/
PHP_FUNCTION(say_hello_func)
{
char *name;
int name_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE)
{
return;
}
php_printf("Hello %s!", name);
RETURN_TRUE;
}
ZEND_BEGIN_ARG_INFO(arginfo_say_hello_func, 0)
ZEND_END_ARG_INFO()
/* }}} */
/* {{{ say_hello_functions[]
然后就可以make 了
qiqi@qiqi-virtual-machine:~/php-5.3.23/ext/say_hello$ /usr/bin/phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
qiqi@qiqi-virtual-machine:~/php-5.3.23/ext/say_hello$ ./configure
...
...
...
qiqi@qiqi-virtual-machine:~/php-5.3.23/ext/say_hello$ make
...
...
qiqi@qiqi-virtual-machine:~/php-5.3.23/ext/say_hello$ sudo make install
...
...
Installing shared extensions: /usr/lib/php5/20090626/
qiqi@qiqi-virtual-machine:/etc/php5/conf.d$ sudo vim say_hello.ini
extension=say_hello.so
qiqi@qiqi-virtual-machine:/etc/php5/conf.d$ sudo /etc/init.d/php5-fpm restart
qiqi@qiqi-virtual-machine:/etc/php5/conf.d$ sudo /etc/init.d/nginx restart
现在就可以使用自己的扩展了。