使用C来开发PHP扩展可以极大的提高运行率,但扩展的开发比较复杂、开发周期长,所以,个中利弊还是要自己权衡。
本文只是开发PHP扩展的一个简单示范,演示一下PHP扩展开发的一般流程,并不深入研究相关的API。
第一步、获取源代码
开发扩展我们首先需要一份与你所使用的PHP版本对应的PHP源代码,因为PHP的源代码中有我们所需要的扩展开发环境。
在这里,我使用的是PHP-5.5.33的源代码。
第二步、生成扩展框架
进入PHP源代码目录下的ext目录,该目录下有一个名为ext_skel
的文件,我们需要用这个文件生成扩展框架。
ext_skel
文件有以下选项1
2
3
4
5
6
7
8
9
10
11
12./ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]]
[--skel=dir] [--full-xml] [--no-help]
--extname=module module is the name of your extension
--proto=file file contains prototypes of functions to create
--stubs=file generate only function stubs in file
--xml generate xml documentation to be added to phpdoc-cvs
--skel=dir path to the skeleton directory
--full-xml generate xml documentation for a self-contained extension
(not yet implemented)
--no-help don't try to be nice and create comments in the code
and helper functions to test if the module compiled
我们要创建一个名为dump的函数,所以终端输入命令:
1 | $ ./ext_skel --extname=dump |
此时,目录下生成了一个名为dump的目录,该目录就是我们的扩展开发环境,其结构如下:1
2
3
4
5
6
7
8
9├── config.m4
├── config.w32
├── CREDITS
├── dump.c
├── dump.php
├── EXPERIMENTAL
├── php_dump.h
└── tests
└── 001.phpt
第三步、更改配置文件
先要修改config.m4文件,将以下三行前面的注释(dnl)去掉:
1 | dnl PHP_ARG_ENABLE(dump, whether to enable dump support, |
第四步、添加函数声明
在php_dump.h的47行:
1 | PHP_FUNCTION(confirm_dump_compiled); /* For testing, remove later. */ |
添加一行我们自己的函数声明:
1 | PHP_FUNCTION(dump); |
第五步、实现相应功能
在dump.c的41行:1
2
3
4const zend_function_entry dump_functions[] = {
PHP_FE(confirm_dump_compiled, NULL) /* For testing, remove later. */
PHP_FE_END /* Must be the last line in dump_functions[] */
};
中添加一行,使其变为:
1 | const zend_function_entry dump_functions[] = { |
在dump.c文件的末尾添加PHP_FUNCTION(dump)函数的实现:
1 | /* 核心代码 */ |
第六步、编译安装扩展
在dump目录下运行:
1 | $ /path/to/phpize |
phpize命令用来准备PHP扩展的编译环境, php-config指明了当前PHP环境的一些信息。
第七步、修改PHP.ini
在php.ini中添加1
extension=dump.so
而后,重启php-fpm服务
第八步、测试
1 | <?php |
运行后输出:
1 | ARRAY: hashtable=0x7f4dbf723278 |
证明扩展载入成功,这样,我们就开发完了一个简单的扩展。