还是360指数项目,需要用到Query归一化,但是公司内只有c++版本的,数据分析的同事用的都是那个二进制可执行文件来处理,但是我们前端又不可能跑system()方法吧,太不安全了,所以要来了源代码,打算封装成一个php扩展。

下边就讲一下我的封装过程。

首先,要到了Query归一化的C++版本源代码。

引用第三方的类库有两种方法,一种是静态引用,一种是动态引用,推荐使用静态引用,因为静态引用的情况下,会把类库打包到php的扩展.SO文件中,这样我们不必担心依赖关系,带着类库到处跑了。

先用gcc产生.o文件,再用.o产生 最终的静态库 .a 文件

上边图中有产生的.o 和 .a文件

如果要动态编译so的话,就是这个:

好,现在有了libqueryword.a静态库,我们就可以开始做我们的扩展了。

先使用ext_skel工具生成我们框架的骨架.

./ext_skel –extname=queryword

把上边的静态库放到 ./lib 目录下。

然后修改config.m4文件。

去掉一些注释符 dnl, 再添加两行,最后config.m4里,有用的就是这几行。

其中:

PHP_REQUIRE_CXX()用于指定这个扩展用到了C++

PHP_ADD_LIBRARY(stdc++, 1, QUERYWORD_SHARED_LIBADD) 用于将标准C++库链接进入扩展

PHP_NEW_EXTENSION用于指定有哪些源文件应该被编译,文件和文件之间用空格隔开.ext_skel默认生成的模块框架是针对C的,我们要使用C++,那以上说明的两个宏就是必须的.另外还要把queryword.c改名成queryword.cpp,所以PHP_NEW_EXTENSION原本包括的queryword.c也要修改.

默认生成的queryword.c(现在改名为queryword.cpp)了,已经包含了一个测试性质的导出函数,通过那个例子就可以大概明白怎么添加自己的函数了. zend_function_entry是导出函数列表, zend_module_entry描述了模块的信息. 不过因为是C++了,还是有几点要修改的,否则跑不起来:

1.cpp中自带的include,需要用extern “C”修饰。

改后如下:

2.ZEND_GET_MODULE也要用extern “C”修饰,这里注意的是,修饰 ZEND_GET_MODULE ,用的是宏。

再说明下,用到的第三方类库的方法,需要声明,上边的extern “C”下边的两个文件,就是我声明的要调用第三方类库的方法的定义。

比如:

放在 include 目录下的 queryword.h 内容如下:

再然后就是编辑自己的代码了,声明一个方法,并在自己的方法里调用第三方的库方法。最后RETURN结果。

这里就不详细说了,,跟自己的模块用法有关。

写好了之后,就一切ok了。

 

剩下的就是 phpize, ./configure , make …等等了。

 

——append  @ 2014-09-04

后期的谈谈项目也封装了一个扩展,就在组内进行了一次分享,有个ppt,分享给大家。

http://fukun.org/dd_share/c-php-extension/ppt.html