商务合作加Q:411239339

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

浏览:993次阅读
没有评论

共计 3186 个字符,预计需要花费 8 分钟才能阅读完成。

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 扩展模块:

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

接着执行如下命令:

/usr/bin/phpize

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

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

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

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

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

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 'https://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

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

正文完
扫码赞助
post-qrcode
 0
果子
版权声明:本站原创文章,由 果子 于2015-12-22发表,共计3186字。
转载说明:除特殊说明外本站文章皆由果较瘦原创发布,转载请注明出处。
评论(没有评论)