技术文章

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的使用方法

Leave a Reply

Free Web Hosting