c++扩展PHP手记(一)
终于有时间研究一下PHP的扩展开发,先来个简单的,
参考:http://my.huhoo.net/archives/2008/06/linuxcphp.html
使用ext_skel简单一些,也就是所谓的动态扩展,静态扩展没研究
首先找到PHP源码文件,找到ext下,然后步骤如下:
1,进入ext下,命令:
server:/data/soft/php/ext # ext_skel --extname = ext_bankie
然后可看到生成有ext_bankie.c/php_ext_bankie.h test文件夹,等等,但是最重要还是config.m4文件,
2,编辑config.m4 ,我的内容如下:
if test "$PHP_EXT_BANKIE" != "no"; then PHP_REQUIRE_CXX() PHP_ARG_ENABLE(ext_bankie, whether to enable ext_bankie support, Make sure that the comment is aligned: [ --enable-ext_bankie Enable ext_bankie support]) PHP_ADD_LIBRARY(stdc++,"", EXTRA_LDFLAGS) PHP_NEW_EXTENSION(ext_bankie, ext_bankie.cpp, $ext_shared) fi
退出,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 用于指定有哪些源文件应该被编译,文件和文件之间用空格隔开;
3,编辑php_ext_bankie.h,
由于TSRM.h这个文件所包含的函数和类都是用纯C语言写的,故应该使用extern来说明如下:
头部加入如下内容:
extern "C" { #ifdef ZTS #include "TSRM.h" #endif }
//这些有关函数的描述
PHP_MINIT_FUNCTION(ext_bankie); PHP_MSHUTDOWN_FUNCTION(ext_bankie); PHP_RINIT_FUNCTION(ext_bankie); PHP_RSHUTDOWN_FUNCTION(ext_bankie); PHP_MINFO_FUNCTION(ext_bankie);PHP_FUNCTION(confirm_ext_bankie_compiled); PHP_FUNCTION(strFun);//这个自己加入一个新函数,,但是没有成功,,稍后会给出原因
编辑完退出。
4,编辑ext_bankie.cpp,注意:ext_bankie.c 修改为ext_bankie.cpp 头部也需要加入:
21 #ifdef HAVE_CONFIG_H 22 #include "config.h" 23 #endif 24 extern "C"{ 25 #include "php.h" 26 #include "php_ini.h" 27 #include "ext/standard/info.h" 28 } 29 #include "php_ext_bankie.h"
//这个方法是加入自己新的函数,相当于注册到ZEND ,PHP_FE宏
zend_function_entry ext_bankie_functions[] = { 43 PHP_FE(confirm_ext_bankie_compiled, NULL) /* For testing, remove later. */ 44 PHP_FE(strFun,NULL) //this is my new function 45 {NULL, NULL, NULL} /* Must be the last line in ext_bankie_functions[] */ 46 };
,文件最后部分要描述一下新加入的函数,strFun
PHP_FUNCTION(strFun) 159 { 160 char *arg = NULL; 161 int arg_len, len; 162 char *strg; 163 164 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) { 165 return; 166 } 167 168 len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "ext_bankie", arg); 169 RETURN_STRINGL(strg, len, 0); 170 }
编辑完退出。
5,这个步骤就可以使用phpize生成可执行的脚本,就是configure文件.找到PHP安装文件下的phpize
server:/data/soft/php/ext/ext_bankie# /usr/local/php/bin/phpize
命令完成后,ext_bankie 下生成了很多文件,不用关心其他的,执行如下命令:
server:/data/soft/php/ext/ext_bankie# ./configure -with-php-config=/usr/local/php-5.2.17/bin/php-config
到此时已经生成了可用于make /make install的脚本。如有error检查config.m4等文件,肯定是哪个步骤有问题了,
6,make, make install
Installing shared extensions: /usr/local/php-5.2.17/lib/php/extensions/no-debug-non-zts-20060613/
生成成功
可以编辑php.ini加入
extension=ext_bankie.so
注意重起apache使用php -m 查看,找到ext_bankie.so,或者使用如下方式:
使用测试文件text.php如下:
4 <?php if (!extension_loaded("ext_bankie")) 5 @ini_set('display_errors', 1); 6 error_reporting(E_ALL ^ E_NOTICE); 7 dl('ext_bankie.so'); 8 $a ='testab'; 9 $re =testFun($a); 10 print $re; ?> 11 12 <?php 13 echo "ext_bankie extension is available"; 14 ?>
执行成功:
Congratulations! You have successfully modified ext/ext_bankie/config.m4. Module testab is now compiled into PHP.ext_bankie extension is available
//后续会增加更深入一些,C++ obj的使用方法