这两天用到了C语言写扩展PHP函数,将过程记录一下。
这里示例扩展了一个函数,它可以将字符串和整形变量连接起来,比如"hello"和1234连接成"hello1234"。
1.新建extstrcat.def,放到ext/目录下
string extstrcat(string strarg, int intarg)
2.新建extstrcattest.php,放到网站目录,它将作为测试页面
<?php
if(!extension_loaded('extstrcat')) {
dl('extstrcat.' . PHP_SHLIB_SUFFIX);
}
$ret=extstrcat('testarg',1234);
echo $ret;
?>
3.创建扩展函数
cd ext/
./ext_skel --extname=extstrcat --proto=extstrcat.def
4.修改ext/extstrcat/config.m4,去掉如下行前面的dnl
PHP_ARG_ENABLE(extstrcat, whether to enable extstrcat support,
Make sure that the comment is aligned:
[ --enable-extstrcat Enable extstrcat support])
5.编辑ext/extstrcat/extstrcat.c,找到PHP_FUNCTION(extstrcat)函数,编写具体的实现
PHP_FUNCTION(extstrcat)
{
char *strarg = NULL;
int argc = ZEND_NUM_ARGS();
int strarg_len;
long intarg;
char intargstr[10];
int retstrlen = 0;
char *retstr = NULL;
if (zend_parse_parameters(argc TSRMLS_CC, "sl", &strarg, &strarg_len, &intarg) == FAILURE)
return;
snprintf(intargstr, 9, "%d", intarg);
retstrlen = strarg_len + strlen(intargstr) + 1;
retstr = (char *)malloc(sizeof(char)* retstrlen);
memset(retstr, '\0', retstrlen);
strncat(retstr, strarg, strlen(strarg));
strncat(retstr, intargstr, strlen(intargstr));
RETURN_STRING(retstr, 1);
php_error(E_WARNING, "extstrcat: not yet implemented");
}
6.编译扩展代码
phpize
./configure --enable-extstrcat
make
7.将生成的动态链接库extstrcat.so复制到PHP的模块目录
cp ./modules/extstrcat.so /usr/local/lib/php/extensions/no-debug-non-zts-20121212/
8.修改php.ini,增加extension = extstrcat.so
9.重启php-fpm,运行phpinfo()可以看到 extstrcat support enabled
10.打开http://127.0.0.1/extstrcattest.php,输出testarg1234,正确。
我实际给PHP扩展了一个自定义的TripleDES的加解密函数,这样PHP就可以解C语言客户端加密出来的数据了,也可以加密数据到C语言客户端解密。