您的位置:首页 > 编程语言 > C语言/C++

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

2011-09-05 13:50 363 查看
如果要用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中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: