`
dengbaoleng
  • 浏览: 1131360 次
文章分类
社区版块
存档分类
最新评论

用 C or C++ 开发PHP扩展模块

 
阅读更多
如果要用C++ 来开发,只需要extern "C" {}将其C的头文件和库定义包含起来就可以,C++可以直接使用C的库,

----------------------------------------------------

得到一份PHP源码,我这里用的是 php-5.3.0.tar.gz
解压
进入到 ext 目录下。
$./ext_skel --extname=jason_php_module//jason_php_module 为自定义的模块名
进入到生成的目录 jason_php_module 目录中,有一些文件和目录。

config.m4 // linux下编译配置文件
config.w32// win32 下编译配置文件
CREDITS
EXPERIMENTAL
jason_php_module.c
jason_php_module.php
php_jason_php_module.h
tests

可以根据提示来修改config.m4文件,这里有几个重要的宏命令如下:

* dnl 是注释;
* PHP_ARG_WITH 或者 PHP_ARG_ENABLE 指定了PHP扩展模块的工作方式,前者意味着不需要第三方库,后者正好相反;
* PHP_REQUIRE_CXX 用于指定这个扩展用到了C++;
* PHP_ADD_INCLUDE 指定PHP扩展模块用到的头文件目录;
* PHP_CHECK_LIBRARY 指定PHP扩展模块PHP_ADD_LIBRARY_WITH_PATH定义以及库连接错误信息等;
* PHP_ADD_LIBRARY(stdc++,"",EXTERN_NAME_LIBADD)用于将标准C++库链接进入扩展
* PHP_SUBST(EXTERN_NAME_SHARED_LIBADD) 用于说明这个扩展编译成动态链接库的形式;
* PHP_NEW_EXTENSION 用于指定有哪些源文件应该被编译,文件和文件之间用空格隔开;

ext_skel默认生成的模块框架是针对C的,
如果我们要使用C++进行PHP扩展, 那除以上的PHP_REQUIRE_CXX, PHP_ADD_LIBRARY两个宏必需外,还要把jason_php_module.c改名成jason_php_module.cpp。
需要注意的是,在config.m4里面可以使用类似的Makefile语法,片段如下:

PHP_REQUIRE_CXX()
INCLUDES="$INCLUDES `mysql_config --cflags`"
PHP_ADD_LIBRARY(stdc++, "", EXTRA_LDFLAGS)
EXTRA_LDFLAGS="$EXTRA_LDFLAGS `mysql_config --libs` -lmemcached"
AC_CHECK_HEADERS([mysql/mysql.h])
CPPFILE="ext_name.cpp antiForbitWord.cpp antiBaseDict.cpp Trie.cpp Logger.cpp antiEncodeConverter.cpp strnormalize.cpp"
PHP_NEW_EXTENSION(ext_name, $CPPFILE, $ext_shared)


----------------------------------------------------
修改php_jason_php_module.h 文件
由于TSRM.h这个文件所包含的函数和类都是用纯C语言写的,故应该使用extern来说明如下:

extern "C" {
#ifdef ZTS
#include "TSRM.h"
#endif
}

如果该php_ext_name.h头文件或者ext_name.cpp文件用到了C++语言中的一些容器或者一些函数,则需要在头文件中包含相应的c++库的头文件,否则会出现找不到相应的C++函数错误。

----------------------------------------------------
修改jason_php_module.cpp这个cpp文件。

由于config.h、php.h、php_ini.h和ext/standard/info.h中包含的函数和类如TSRM.h一样,都是用纯C语言写的,所以也需要用extern说明如下:

extern "C" {
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
}

而 #include "php_ext_name.h" 这句则已经不需要包含在extern "C"内,另外,ZEND_GET_MODULE这个宏命令也是需要特别申明如下:

#ifdef COMPILE_DL_EXT_NAME
BEGIN_EXTERN_C()
ZEND_GET_MODULE(ext_name)
END_EXTERN_C()
#endif

总之,把一些C写的库或轰用兼容的方式给解决

---------------------------------------------------
现在可以去编译扩展模块了。如果你想把它编译成静态模块(把它做为PHP的一个部分编译进PHP中去),去到PHP的根目录$PHP_HOME,删去 configure 文件和运行buildconf (译:需要libtool的支持)。

然后用你平常用的参数运行 configure 并加上--enable-php5cpp 项。运行 make clean, make, make install ,并完成其它的一些必要操作,如:重新编译Apache。

如果你想用动态链接库的方式编译扩展模块,到你的模块的目录下,运行phpize 命令(假设你已经安装了PEAR),它会为你的模块创建一个 configure 脚本。然后运行configure, make 和 make install。如果你想让你的模块自动加载,你要修改php.ini 以加载正确的文件。如:加上类似的一行:extension=php5cpp.so 。

$phpize
$./configure
$make

注意:

在运行 Phpize命令之后 如果出现错误

Configuring for:
PHP Api Version: 20041225
Zend Module Api No: 20060613
Zend Extension Api No: 220060519
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.

根据网上的解决办法是:

# fetch http://ftp.gnu.org/gnu/m4/m4-1.4.9.tar.gz

# tar -zvxf m4-1.4.9.tar.gz # cd m4-1.4.9/

# ./configure && make && make install # cd ../

# fetch http://ftp.gnu.org/gnu/autoconf/autoconf-2.62.tar.gz

# tar -zvxf autoconf-2.62.tar.gz # cd autoconf-2.62/

# ./configure && make && make install

这样就可以了

用phpize生成configure执行文件后,可以用./configure --help查看帮助信息,修改config.m4文件可以修改configure的帮助信息。每次修改了config.m4文件,需要使用清除临时文件命令phpize --clean来完成消除configure。

现在你的PHP扩展模块已经编译好了。试着运行一下在模块目录下自动生成的php5cpp.php ,看看是不是一切正常?:)

------------------------------------
怎么使用写好的扩展就不细说了
调试的时候,可以在PHP 里用 dl('jason_php_module.so');
应用中,可以根据情况编译进PHP中,或配置进PHP中。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics