一步一步编写PHP扩展模块及调用C/C++动态库

2015/12/2221:04:55 发表评论

1、环境说明

系统:CentOS 6.X

yum默认安装的LAMP环境(对LAMP不明觉厉害的童鞋可以先去和百度大妈共度下良宵)

PHP版本:5.3.X

Apache:2.2.15

2、获取PHP源码

由于CentOS默认是以RPM二进制方式安装的软件包,为了自行编写PHP扩展模块,我们还是下载一个5.3.27的源码好了,实际上5.3.X的版本都是可以的。

http://cn2.php.net/distributions/php-5.3.27.tar.gz

3、建立扩展模块目录

cd /opt
wget http://cn2.php.net/distributions/php-5.3.27.tar.gz
tar zxf php-5.3.27.tar.gz
cd php-5.3.27/ext
./ext_skel --extname=hello

此时会在php-5.3.27/ext目录下生成一个名叫hello的目录,输出如下信息:

Creating directory hello
Creating basic files: config.m4 config.w32 .svnignore hello.c php_hello.h CREDITS EXPERIMENTAL tests/001.phpt hello.php [done].

To use your new extension, you will have to execute the following steps:

$ cd ..
$ vi ext/hello/config.m4
$ ./buildconf
$ ./configure --[with|enable]-hello
$ make
$ ./php -f ext/hello/hello.php
$ vi ext/hello/hello.c
$ make

Repeat steps 3-6 until you are satisfied with ext/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.

到现在为止,我们的模块环境已经准备好了,那么如何来链接我们的C/C++开发的动态库呢,比如libhello.so,请往下看。

4、生成动态库文件libhello.so

新建一个目录/opt/libhello,进入该目录:

mkdir /opt/libhello
cd /opt/libhello

用vim打开hello.c输入以下内容:

#include <stdio.h>
int cc_add(int a,int b)
{
    return a + b;
}

编译命令如下:

gcc -O -fPIC -c -o hello.o hello.c 
gcc -shared -o libhello.so hello.o
#拷贝动态库至/usr/local/lib
cp libhello.so  /usr/local/lib
#添加动态库至系统LD PATH
echo "/usr/local/lib" >> /etc/ld.so.conf
ldconfig

编写一个main.c来测试一下:

#include <stdio.h>
int main()
{
    printf("%d\n",cc_add(1,2));
    return 0;
}

编译运行:

gcc -o main main.c -lhello
./main
#输出结果为3

至此,我们的C/C++业务模块已经开发完成了,接下来,我们要来真刀真枪干了,准备写PHP扩展,听起来好像很高大上的样子哦~_~

5、配置PHP扩展模块

cd /opt/php-5.3.27/ext/hello
#修改文件config.m4的如下几行,其中dnl为注释开头符,去掉大概第10行和12行的dnl即可,相信编译过PHP源码的童鞋已经清楚了,这个--with-hello选项是可以直接把hello模块静态编译进PHP中的,下面我们说的只是如何编译成动态的PHP扩展模块:

1

接着执行如下命令:

/usr/bin/phpize

打开 php_hello.h,在 PHP_FUNCTION(confirm_hello_compiled); 之下加入函数声明(需要添加几个函数写几个):

2

打开 hello.c,在 PHP_FE(confirm_hello_compiled, NULL) 下方加入以下内容(需要添加几个函数写几个,这里只添加了一个hello_add函数)。

2

接着在文件最后加上如下代码:

PHP_FUNCTION(hello_add)  
{  
    long int a, b;  
    long int result;  
  
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &a, &b) == FAILURE) {  
        return;  
    }  
    result = cc_add(a, b);  
  
    RETURN_LONG(result);  
}

关于zend_parse_parameters函数的参数,这里做下说明,更多请参考文章链接:

http://www.nowamagic.net/librarys/veda/detail/1467

type_spec是格式化字符串,其常见的含义如下:
参数   代表着的类型
b   Boolean
l   Integer 整型
d   Floating point 浮点型
s   String 字符串
r   Resource 资源
a   Array 数组
o   Object instance 对象
O   Object instance of a specified type 特定类型的对象
z   Non-specific zval 任意类型~
Z   zval**类型
f   表示函数、方法名称,PHP5.1里貌似木有... ...

6、开始联合编译

./configure --with-php-config=/usr/bin/php-config 
make LDFLAGS=-lhello   #此处也可以直接修改Makefile文件实现
make install

7、将新模块配置进PHP环境中

vim /etc/php.d/hello.ini
; Enable hello extension module
extension=hello.so
#重启apache模块
/etc/init.d/httpd restart
#查看模块
php -m | grep hello

进入WEB目录,我的默认为/var/www/html,新建一个网页文件hello.php:

<html>
<title>欢迎来到果子实验室</title>
<body>
<?php
echo '<h1>Welcome to Guozi blog<br/>';
echo 'http://www.guoziweb.com/<br/>';
echo 'Module hello begin...<br/>';
echo hello_add(2,3);
echo '<br/>Module hello end...<br/>';
echo 'Thank you!</h1><br/>';
?>
</body>
</html>

8、打开网页欣赏战果

我的内网机器IP为192.168.128.7,所以打开网页链接为:http://192.168.128.7/hello.php

3

  • 微信扫码赞助
  • weinxin
  • 支付宝赞助
  • weinxin
  • A+
所属分类:PHP

发表评论

您必须才能发表评论!