共计 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 输入以下内容:
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 来测试一下:
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 扩展模块:
接着执行如下命令:
/usr/bin/phpize
打开 php_hello.h,在 PHP_FUNCTION(confirm_hello_compiled); 之下加入函数声明 (需要添加几个函数写几个):
打开 hello.c,在 PHP_FE(confirm_hello_compiled, NULL) 下方加入以下内容 (需要添加几个函数写几个,这里只添加了一个 hello_add 函数)。
接着在文件最后加上如下代码:
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 | |
/etc/init.d/httpd restart | |
php -m | grep hello |
进入 WEB 目录,我的默认为 /var/www/html,新建一个网页文件 hello.php:
<html> | |
<title> 欢迎来到果子实验室 </title> | |
<body> | |
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
