在Linux下用C扩展PHP(打包成so)的方法
2016-02-01 00:00
666 查看
/article/2751309.html
本文主要讲一下在Linux下用打包C扩展程序.so文件和Windows下的不同,详细的代码和配置方案请参加另一篇博客:/article/2751304.html
步骤:
1.安装php环境到目录 /usr/local/php/ 目录下
2.下载相同版本的php源码包,安装到 /root/php-5.6.9/ 目录下,可到官网http://www.php.net/downloads.php下载
执行命令:
[cpp] view plaincopyprint?
cd /root
wget http://us1.php.net/distributions/php-5.6.9.tar.bz2
tar -xf php-5.6.9.tar.bz2
注意,有一些历史版本没有源码包,需要升级php到提供源码包的版本
3.到 /php-5.6.9/ext/ 目录下,使用ext_skel生成扩展骨架
[cpp] view plaincopyprint?
cd ./php-5.6.9/ext
./ext_skel --extname=test
4.修改配置文件 /test/config.m4
取消下面两行的dnl注释:
[cpp] view plaincopyprint?
PHP_ARG_ENABLE(test, whether to enable test support,
dnl Make sure that the comment is aligned:
[ --enable-test Enable test support])
如果要使用C++进行编译,要将test.c改名为test.cpp,并在config.m4中添加
[cpp] view plaincopyprint?
PHP_REQUIRE_CXX()
PHP_ADD_LIBRARY(stdc++, 1, EXTRA_LDFLAGS)
PHP_NEW_EXTENSION(test, test.cpp, $ext_shared)
5.在php_test.h文件中添加代码,加入自定义的函数声明:
[cpp] view plaincopyprint?
PHP_MINIT_FUNCTION(test);
PHP_MSHUTDOWN_FUNCTION(test);
PHP_RINIT_FUNCTION(test);
PHP_RSHUTDOWN_FUNCTION(test);
PHP_MINFO_FUNCTION(test);
PHP_FUNCTION(confirm_test_compiled); /* For testing, remove later. */
PHP_FUNCTION(testFunc);
6.在test.c/cpp中添加自定义函数代码:
(1)首先,在这个位置引入用到的头文件:
[cpp] view plaincopyprint?
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include
#include
[cpp] view plaincopyprint?
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_test.h"
否则,会出现很多函数重定义的问题,详见另一篇博客:http://blog.csdn.net/maverick1990/article/details/46786685
(2)然后,在这个位置添加函数入口:
[cpp] view plaincopyprint?
const zend_function_entry test_functions[] = {
PHP_FE(confirm_test_compiled, NULL) /* For testing, remove later. */
PHP_FE(testFunc, NULL)
PHP_FE_END /* Must be the last line in test_functions[] */
};
(3)最后,在文件尾部添加testFunc函数的代码,也可以在这里定义其他自定义函数
[cpp] view plaincopyprint?
PHP_FUNCTION(testFunc)
{
char *x = NULL;
char *y = NULL;
int argc = ZEND_NUM_ARGS();
int x_len;
int y_len;
if (zend_parse_parameters(argc TSRMLS_CC, "ss", &x, &x_len, &y, &y_len) == FAILURE)
return;
int result_length = x_len + y_len;
char* result = (char *) emalloc(result_length + 1);
strcpy(result, x);
strcat(result, y);
RETURN_STRINGL(result, result_length, 0);
}
关于PHP_FUNCTION函数的书写方法,详见博客:http://weizhifeng.net/write-php-extension-part2-1.html
7.在 /root/php-5.6.9/ext/test/ 目录下,建立php扩展模块:
[cpp] view plaincopyprint?
phpize
可能需要加上路径:
[cpp] view plaincopyprint?
/usr/local/php/bin/phpize
8.回到 /root/php-5.6.9/ 目录,重新建立编译需要的配置:
[cpp] view plaincopyprint?
cd ../..
./buildconf --force
若出现类似的报错:
[cpp] view plaincopyprint?
buildconf: You need autoconf 2.59 or lower to build this version of PHP.
You are currently trying to use 2.63
Most distros have separate autoconf 2.13 or 2.59 packages.
On Debian/Ubuntu both autoconf2.13 and autoconf2.59 packages exist.
Install autoconf2.13 and set the PHP_AUTOCONF env var to
autoconf2.13 and try again.
那么,通过下面的方法解决:
[cpp] view plaincopyprint?
yum install autoconf213
export PHP_AUTOCONF=/usr/bin/autoconf-2.13
9.再到 /root/php-5.6.9/ext/test/ 目录下,生成配置:
[cpp] view plaincopyprint?
./configure --with-php-config=/usr/local/php/bin/php-config
10.编译并生成.so扩展文件
[cpp] view plaincopyprint?
make
make install
若make出错,修改代码直到编译通过
若make install出错,修改后,需要清空当前生成的扩展模块:
[cpp] view plaincopyprint?
phpize --clean
然后从第7步重新开始
11.查看test.so是否生成
make install成功后会给出生成路径,例如:/usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/test.so
12.修改php.ini
修改 /usr/local/php/etc/php.ini 文件,加入扩展路径和名称:
[cpp] view plaincopyprint?
extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/"
extension = "teste.so"
13.重启PHP服务
[cpp] view plaincopyprint?
service php-fpm restart
14.在PHP中使用C++扩展函数
[cpp] view plaincopyprint?
<!--?php
$concat_str = testFunc("concat1","concat2");
echo $concat_str;
?>
注意:若使用扩展函数时出现错误:
[cpp] view plaincopyprint?
PHP Warning PHP Startup Unable to initialize module
Module compiled with module API=20121212 PHP
compiled with module API=20090626
These options need to match in Unknown on line 0
这是由于编译.so文件的php源码包版本和当前使用的php版本不同所致,需要在下载当前版本的php源码包,重新编译扩展
本文主要讲一下在Linux下用打包C扩展程序.so文件和Windows下的不同,详细的代码和配置方案请参加另一篇博客:/article/2751304.html
步骤:
1.安装php环境到目录 /usr/local/php/ 目录下
2.下载相同版本的php源码包,安装到 /root/php-5.6.9/ 目录下,可到官网http://www.php.net/downloads.php下载
执行命令:
[cpp] view plaincopyprint?
cd /root
wget http://us1.php.net/distributions/php-5.6.9.tar.bz2
tar -xf php-5.6.9.tar.bz2
注意,有一些历史版本没有源码包,需要升级php到提供源码包的版本
3.到 /php-5.6.9/ext/ 目录下,使用ext_skel生成扩展骨架
[cpp] view plaincopyprint?
cd ./php-5.6.9/ext
./ext_skel --extname=test
4.修改配置文件 /test/config.m4
取消下面两行的dnl注释:
[cpp] view plaincopyprint?
PHP_ARG_ENABLE(test, whether to enable test support,
dnl Make sure that the comment is aligned:
[ --enable-test Enable test support])
如果要使用C++进行编译,要将test.c改名为test.cpp,并在config.m4中添加
[cpp] view plaincopyprint?
PHP_REQUIRE_CXX()
PHP_ADD_LIBRARY(stdc++, 1, EXTRA_LDFLAGS)
PHP_NEW_EXTENSION(test, test.cpp, $ext_shared)
5.在php_test.h文件中添加代码,加入自定义的函数声明:
[cpp] view plaincopyprint?
PHP_MINIT_FUNCTION(test);
PHP_MSHUTDOWN_FUNCTION(test);
PHP_RINIT_FUNCTION(test);
PHP_RSHUTDOWN_FUNCTION(test);
PHP_MINFO_FUNCTION(test);
PHP_FUNCTION(confirm_test_compiled); /* For testing, remove later. */
PHP_FUNCTION(testFunc);
6.在test.c/cpp中添加自定义函数代码:
(1)首先,在这个位置引入用到的头文件:
[cpp] view plaincopyprint?
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include
#include
[cpp] view plaincopyprint?
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_test.h"
否则,会出现很多函数重定义的问题,详见另一篇博客:http://blog.csdn.net/maverick1990/article/details/46786685
(2)然后,在这个位置添加函数入口:
[cpp] view plaincopyprint?
const zend_function_entry test_functions[] = {
PHP_FE(confirm_test_compiled, NULL) /* For testing, remove later. */
PHP_FE(testFunc, NULL)
PHP_FE_END /* Must be the last line in test_functions[] */
};
(3)最后,在文件尾部添加testFunc函数的代码,也可以在这里定义其他自定义函数
[cpp] view plaincopyprint?
PHP_FUNCTION(testFunc)
{
char *x = NULL;
char *y = NULL;
int argc = ZEND_NUM_ARGS();
int x_len;
int y_len;
if (zend_parse_parameters(argc TSRMLS_CC, "ss", &x, &x_len, &y, &y_len) == FAILURE)
return;
int result_length = x_len + y_len;
char* result = (char *) emalloc(result_length + 1);
strcpy(result, x);
strcat(result, y);
RETURN_STRINGL(result, result_length, 0);
}
关于PHP_FUNCTION函数的书写方法,详见博客:http://weizhifeng.net/write-php-extension-part2-1.html
7.在 /root/php-5.6.9/ext/test/ 目录下,建立php扩展模块:
[cpp] view plaincopyprint?
phpize
可能需要加上路径:
[cpp] view plaincopyprint?
/usr/local/php/bin/phpize
8.回到 /root/php-5.6.9/ 目录,重新建立编译需要的配置:
[cpp] view plaincopyprint?
cd ../..
./buildconf --force
若出现类似的报错:
[cpp] view plaincopyprint?
buildconf: You need autoconf 2.59 or lower to build this version of PHP.
You are currently trying to use 2.63
Most distros have separate autoconf 2.13 or 2.59 packages.
On Debian/Ubuntu both autoconf2.13 and autoconf2.59 packages exist.
Install autoconf2.13 and set the PHP_AUTOCONF env var to
autoconf2.13 and try again.
那么,通过下面的方法解决:
[cpp] view plaincopyprint?
yum install autoconf213
export PHP_AUTOCONF=/usr/bin/autoconf-2.13
9.再到 /root/php-5.6.9/ext/test/ 目录下,生成配置:
[cpp] view plaincopyprint?
./configure --with-php-config=/usr/local/php/bin/php-config
10.编译并生成.so扩展文件
[cpp] view plaincopyprint?
make
make install
若make出错,修改代码直到编译通过
若make install出错,修改后,需要清空当前生成的扩展模块:
[cpp] view plaincopyprint?
phpize --clean
然后从第7步重新开始
11.查看test.so是否生成
make install成功后会给出生成路径,例如:/usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/test.so
12.修改php.ini
修改 /usr/local/php/etc/php.ini 文件,加入扩展路径和名称:
[cpp] view plaincopyprint?
extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/"
extension = "teste.so"
13.重启PHP服务
[cpp] view plaincopyprint?
service php-fpm restart
14.在PHP中使用C++扩展函数
[cpp] view plaincopyprint?
<!--?php
$concat_str = testFunc("concat1","concat2");
echo $concat_str;
?>
注意:若使用扩展函数时出现错误:
[cpp] view plaincopyprint?
PHP Warning PHP Startup Unable to initialize module
Module compiled with module API=20121212 PHP
compiled with module API=20090626
These options need to match in Unknown on line 0
这是由于编译.so文件的php源码包版本和当前使用的php版本不同所致,需要在下载当前版本的php源码包,重新编译扩展
相关文章推荐
- CentOS 6 + bochs-2.6 + gdb 调试 linux 0.11 —— 成功
- Linux sed 高级用法实例
- CentOS 7编译rtlwifi_new失败——需要升级内核
- 红帽CEO:员工经常当面叫我笨蛋
- CentOS 6 bochs-2.6 gdb 调试 linux 0.11——bochsrc-fd1-gdb.bxrc
- (OK) 编译cBPM-CentOS7-codeblocks
- (OK) Linux epoll模型—socket epoll server client chat—pthread
- Linux系统各发行版镜像下载(持续更新)---download
- How to build qemu-system-arm in Linux
- 《Linux操作系统》——教学进度表20140218——张同光
- CentOS 6 bochs-2.6 gdb 调试 linux 0.11——bochsrc-hdc-gdb.bxrc
- 《Linux操作系统》——实验课教学进度表20140218——12计科1班——张同光
- (OK) CentOS 7—adb—android-sdk_r24.3.3-linux.tgz
- I need to learn ARM assembly, and I use Linux.
- 《Linux操作系统》——实验课教学进度表20140218——12计科2班——张同光
- Linux C语言连接MySQL 增删改查操作
- (OK) 编译cBPM—CentOS7—gdb—gdbserver—成功—调试
- 安装 Express —— CentOS 7
- (OK) CentOS7 中使用 QQ的方法建议——VirtualBox + WinXP
- (OK) 调试cBPM—CentOS7—gdb—gdbserver—问题的解决—1—手机死机