使用C++开发PHP扩展
简单事例
准备工作:
- 下载PHP源码 传送门 选择需要的版本下载
- 解压放置安装目录如:/usr/local/php-版本号/
- 配置php.ini的路径,方便个性化配置 (to do)
- 要编写的扩展名称"dishcl"
- 要编写的扩展函数:dishcl_say(),//内容只返回一个hello world字符串
- 扩展可运行在 win32 系统,也运行在类unix系统,但是需要编译不同的文件,这里只介绍 GNU/Linux 下的操作。
操作:
- 创建要实现的函数列表文件dishcl.proto,内容如下: 位置任意你知道的位置
string dishcl_say()
- 使用扩展骨架工具生成核心文件,执行命令如下:可参考php-版本号/ext/目录下的ext_skel.php 中的操作
cd php-版本号/ext/ #进入扩展目录
php ./ext_skel.php --ext dishcl --dir ../../php_ext/ #(dishcl.proto文件位置)
这时就在 php_ext 目录下出现了 dishcl 文件夹,里面包含几个文件,如:config.m4 dishcl.c php_dishcl.h 等等。
3. 配置config.m4
去掉“dnl PHP_ARG_WITH(dishcl, for dishcl support,”和“dnl [ --with-dishcl Include dishcl support])”前面的注释(dnl是注释的意思),去掉后的效果如下图:
- 编写扩展
dishcl.cpp
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_discuz.h"
#include <string> /* 添加这行 */
//修改以下内容
PHP_FUNCTION(dishcl_say)
{
std::string str = "Hello world!";
RETURN_STRINGL(str.c_str(), str.length(), 1);
}
//或者以下另一个函数
PHP_FUNCTION(dishcl_counter)
{
long arg_add1 = 0;
long arg_add2 = 0;
long sum = 0;
size_t arg_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &arg_add1, &arg_add2, &arg_len) == FAILURE) {
return;
}
sum = arg_add1 + arg_add2;
RETURN_LONG(sum);
}
> 在zend_function_entry中加入:PHP_FE(smart_counter, NULL)
- 编译扩展
phpize
./configure --prefix=/usr/bin/php7.2 #(php可执行文件位置)
make && make install
出现如下提示说明编译成功:
Build complete.
Don’t forget to run ‘make test’.
Installing shared extensions: (这就是hclg.so的存放位置) …
安装并测试
- 修改php.ini
php --ini #查看php.ini的位置
vim /etc/php/7.2/cli/php.ini
在该文件中添加:
extension=(hclg.so的位置)
查看是否配置上
php7.2 -m
最后直接写php文件执行一下即可
待更新遍历脚本(暂不可用):
phpize
./configure --prefix=/usr/bin/php7.2 #(php可执行文件位置)
make && make install
# kill -USR2 对应的PID #如果没有配上重启一下php-fpmroot
php7.2 -m