编制自己的php扩展
2013-03-21 19:31
363 查看
下面列出自己的实战步骤,主要涉及到这3个文件:
config.m4:这是Unix环境下的Build System配置文件,后面将会通过它生成配置和安装。
php_say_hello.h:这是扩展模块的头文件。这个里面可以放置一些自定义的结构体、全局变量等等。
say_hello.c:这是扩展模块的主程序文件,最终的扩展模块各个函数入口都在这里。
把文件中这三行的dnl删掉,打开注释。
其中zend_module_entry 的结构定义如下,写在Zend/zend_modules.h中,或者参考http://www.php.net/manual/en/internals2.structure.modstruct.php
第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的主函数:
然后就可以make 了
现在就可以使用自己的扩展了。
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
现在就可以使用自己的扩展了。
相关文章推荐
- 自己动手用C扩展PHP(一)
- 自己写PHP扩展之创建一个普通变量
- 写5个不同的自己的函数,来截取一个全路径的文件的扩展名,允许封装php库中已有的函数。
- 自己动手用C扩展PHP(二)
- 自己动手用C扩展PHP(二)
- 自己写PHP扩展之创建一个类
- Mac下安装PHP的mcrypt扩展的方法(自己总结的)
- 自己动手用 C 扩展 PHP
- 自己动手用C扩展PHP(三)
- 自己动手用C扩展PHP(三)
- [转]自己写PHP扩展之创建一个类
- 自己写PHP扩展之操作类的属性和方法
- system\classes\Kohana.php 空的核心扩展文件也可以把它复制到application\classes下面写自己的扩展
- 自己写PHP扩展之创建一个类
- 自己尝试着写PHP扩展
- 菜鸟学php扩展 之 实战如何在扩展里调第三方函数(标准库/原生/自己写的)(六)
- 自己写PHP扩展之实现类的继承
- 自己动手用C扩展PHP(二)
- 自己动手用C扩展PHP(三)
- 写 5个不同的自己的函数来获取一个全路径的文件的扩展名, 允许封装php 库中已有 的函数(新浪)