PHP扩展模块开发简解
做PHP开发也有些年了,但是一直都没有做过扩展模块开发,出来工作了,没多少自己的时间了,学东西不能随心所欲了,要按工作需要来。前段时间因为服务器硬盘崩溃,数据损坏,软件注册的PHP程序加密解密部分没有备份,而这部分就是用c开发的,所以只能再次编译进php里了。在网上查了比较多的相关资料,其实都没有几个全的,步骤也不是很完整,所以就有了这片拙作,抛砖引玉吧!
为了方便陈述,把php的编译目录简称为 phpsrc(如:/home/src/php-4.4.4) ,安装目录简称为 phpbin(如 /usr/local/php)
在shell下输入(以后遇到有shell的地方我就用#开头,不另陈述)
为了方便陈述,把php的编译目录简称为 phpsrc(如:/home/src/php-4.4.4) ,安装目录简称为 phpbin(如 /usr/local/php)
在shell下输入(以后遇到有shell的地方我就用#开头,不另陈述)
# cd phpsrc/ext
# ./ext_skel --extname=test_module
# ./ext_skel --extname=test_module
Creating directory test_module
Creating basic files: config.m4 .cvsignore test_module.c php_test_module.h CREDITS EXPERIMENTAL tests/001.phpt test_module.php [done].
To use your new extension, you will have to execute the following steps:
1. $ cd ..
2. $ vi ext/test_module/config.m4
3. $ ./buildconf
4. $ ./configure --[with|enable]-test_module
5. $ make
6. $ ./php -f ext/test_module/test_module.php
7. $ vi ext/test_module/test_module.c
8. $ make
Repeat steps 3-6 until you are satisfied with ext/test_module/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.
Creating basic files: config.m4 .cvsignore test_module.c php_test_module.h CREDITS EXPERIMENTAL tests/001.phpt test_module.php [done].
To use your new extension, you will have to execute the following steps:
1. $ cd ..
2. $ vi ext/test_module/config.m4
3. $ ./buildconf
4. $ ./configure --[with|enable]-test_module
5. $ make
6. $ ./php -f ext/test_module/test_module.php
7. $ vi ext/test_module/test_module.c
8. $ make
Repeat steps 3-6 until you are satisfied with ext/test_module/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.
系统提供的那几步你想做也可以,不想做也没什么影响,继续跟着我做。
# cd test_module
# vi config.m4
# vi config.m4
找到这行
dnl [ --enable-test_module Enable test_module support])
改为
[ --enable-test_module Enable test_module support]
后面那个”)“要去掉,要不./configure的时候会报错。这样以后你编译php想加入你模块的时候在configure后面加 --enable-test_module 就可以加载你的php模块了!
dnl [ --enable-test_module Enable test_module support])
改为
[ --enable-test_module Enable test_module support]
后面那个”)“要去掉,要不./configure的时候会报错。这样以后你编译php想加入你模块的时候在configure后面加 --enable-test_module 就可以加载你的php模块了!
#vi php_test_module.h
找到这段
PHP_FUNCTION(confirm_test_module_compiled); /* For testing, remove later. */
改为:
PHP_FUNCTION(test_module);
# vi test_module.c
找到这段:
/* {{{ test_module_functions[]
*
* Every user visible function must have an entry in test_module_functions[].
*/
zend_function_entry test_module_functions[] = {
PHP_FE(test_module, NULL) / *新增这一行*/
//PHP_FE(confirm_test_module_compiled, NULL) /*注释掉这一行*/ /* For testing, remove later. */
{NULL, NULL, NULL} /* Must be the last line in test_module_functions[] */
};
找到这段
PHP_FUNCTION(confirm_test_module_compiled)
{
char *arg = NULL;
int arg_len, len;
char string[256];
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
return;
}
len = sprintf(string, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "test_module", arg);
RETURN_STRINGL(string, len, 1);
}
改为:
PHP_FUNCTION( test_module)
{
zend_printf("This is a test module !");
}
#红色部分:以后在php 使用这个函数名来调用
# cd phpsrc/ext
# cc -fpic -DCOMPILE_DL_TEST_MODULE=1 -I/usr/local/include -I. -I../main -I.. -I../TSRM -I../Zend -c -o test_module/test_module.o test_module/test_module.c
# cc -fpic -DCOMPILE_DL_TEST_MODULE=1 -I/usr/local/include -I. -I../main -I.. -I../TSRM -I../Zend -c -o test_module/test_module.o test_module/test_module.c
执行完之后会在 目录下生成一个test_module.o文件,接下来连接:
# cc -shared -L/usr/local/lib -rdynamic -o test_module/test_module.so test_module/test_module.o
# mkdir -p phpbin/lib/php/extensions/ (其实这个目录就是看你php.ini里设置extension_dir了)
# cp test_module/test_module.so phpbin/lib/php/extensions/
# mkdir -p phpbin/lib/php/extensions/ (其实这个目录就是看你php.ini里设置extension_dir了)
# cp test_module/test_module.so phpbin/lib/php/extensions/
在web目录下新建一个test.php文件,在里面写入
执行,如果过程无误,将会显示:
This is a test module !
当然,这样的方法只适合我们开发初期调试用,到正式用的时候我们可以用 ./configure --enable-test_module 一起编译进去。又或者你的apache工作在work模式下,你可以修改你的php.ini,加入 extension=test_module.so 来加载你的模块。这是比较简单的c扩展了,实际应用中我们的程序可能不仅一个函数,可能还要用到一些外部的库,那还要link过来一起编译,还要自己写Makefile。唉,这方面我也不是很通,头疼着呢。其实有时候想想还是Java好,跨平台,移植不用费心啊!
参考资料:
http://bbs.chinaunix.net/viewthread.php?tid=547568
http://www.toplee.com/blog/?p=56
http://www.casaby.com/blog/archives/2006/11/_c_php.html
PHP_FUNCTION(test_module)
{
zval **yourname;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &yourname) == FAILURE)
{
WRONG_PARAM_COUNT;
}
zend_printf("hello world, %s/n", Z_STRVAL_PP(yourname));
}