php取得成功的一个主要原因之一是它拥有大量的可用扩展,web开发者无论有何种需求,这种需求最有可能在php发行包里找到
php发行包包括支持各种数据库,图形文件格式,压缩,XML技术扩展在内的许多扩展,PHP扩展(PECL)跟php引擎一样都是使用c语言开发
php扩展开发需要注意什么?
1、开发扩展比使用PHP开发相同功能成本与难度都要更高
2、后期维护不易
3、系统及PHP版本更新导致的一些兼容性问题
4、测试服务器和正式服务器的系统版本、php版本、gcc版本、glibc版本都要保持一致
什么时候需要开发php扩展?
1、对效率要求很高,特别是运算效率
2、功能与业务无关或关联很小,相对抽象
3、功能基本不会变动,且不会很复杂
4、功能使用php无法实现的或者资源无法访问
系统环境:
CentOS release 6.6 (Final) 64位
gcc version 4.4.7, Glibc 2.12
PHP 5.3.3 (cli)
php c扩展开发步骤:这里简单以实现两数相乘并返回结果为例
第一步,生成代码
php为了扩展开发的方便,提供了一个类似代码生成器的工具ext_skel,--extname=test中的test是自定义的函数名称
下载和系统php版本一致的源码包,我默认yum安装,php版本是5.3.3,所以下载php-5.3.3.tar.gz
cd /usr/local/
tar -zxvf php-5.3.3.tar.gz
cd php-5.3.3/ext/
./ext_skel --extname=test
可以看到目录下新增了一个test文件夹,这时候,test这个扩展的代码框架就已经出来了
第二步,修改配置
进入test文件夹下
cd test
然后修改config.m4文件将10、11、12三行最前面的dnl删除掉,就是将
dnl PHP_ARG_WITH(test, for test support,
dnl Make sure that the comment is aligned:
dnl [ --with-test Include test support])
修改为
PHP_ARG_WITH(test, for test support,
Make sure that the comment is aligned:
[ --with-test Include test support])
第三步,实现功能
头文件php_test.h中声明一个函数test,方法:
将45行左右的
PHP_FUNCTION(confirm_test_compiled);
修改为:
PHP_FUNCTION(test);
源代码test.c中实现这个函数,方法:
将154行左右的
PHP_FUNCTION(confirm_test_compiled)
{
char *arg = NULL;
int arg_len, len;
char *strg;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
return;
}
len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "test", arg);
RETURN_STRINGL(strg, len, 0);
}
替换为:
PHP_FUNCTION(test){
/*定义一个int 型变量*/
long a;
long b;
char *c;
/* 字符串在c中使用指针,并且需要指定长度*/
int c_len;
/* 此处字符串一个s 对应两个参数*/
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lls", &a, &b,&c,&c_len) == FAILURE) {
return;
}
char * str;
int len = spprintf(&str, 0, "%s:%d\n",c,a*b);
/*可以在zend_api下查看*/
RETURN_STRINGL(str, len, 0);
}
注意,还需要将test函数注册到zend_api中,否则会报not found
const zend_function_entry test_functions[] = {
/*扩展定义的函数*/
PHP_FE(test,NULL)
{NULL, NULL, NULL} /* Must be the last line in test_functions[] */
};
说明:
1、PHP_FUNCTION:是PHP核心定义的一个宏,与ZEND_FUNCTION相同,用于定义扩展函数,实际生成的函数名称为zif_ip2long32。
2、zend_parse_parameters:由于PHP为弱类型语言,而C是强类型,因此需要使用该函数用于接收PHP传入的参数,并进行一定的类型转换,将PHP的变量转为C语言能够辨认的类型。
第四步,编译扩展
/usr/bin/phpize #生成configure文件
./configure --with-php-config=/usr/bin/php-config #替换为自己环境的php-config路径
make && make install
成功会提示:Installing shared extensions: /usr/lib64/php/modules/
第五步,添加扩展
echo "[test]" >> /etc/php.ini
echo "extension = test.so" >> /etc/php.ini
命令行查看扩展
php -m|grep test
重启httpd服务
service httpd restart
第六布,测试
test.php
<?php
echo test(10,20,"result");
?>
结果: