Swoole-1.9.7增加了一个新特性,可以基于Swoole使用C++语言开发扩展模块,在扩展模块中可以注册PHP内置函数和类。现在可以基于Swoole来编写PHP扩展了。Swoole使用了C++ 11封装了ZendAPI,配合C++ IDE的自动提示和自动补齐,使PHP扩展开发的效率得到了大幅提升,分分钟写出一个PHP扩展。
环境准备
- IDE建议使用Eclipse CDT
- 必须安装Swoole-1.9.7或更高版本
- 必须要有Swoole源码
编写程序
#include <string>
#include <iostream>
#include "PHP_API.hpp"
#include "module.h"
using namespace std;
using namespace PHP;
extern "C"
{
int swModule_init(swModule *);
void swModule_destory(swModule *);
}
//C++函数必须要在头部声明
void cpp_hello_world(Args &args, Variant &retval);
int swModule_init(swModule *module)
{
module->name = (char *) "test";
PHP::registerFunction(function(cpp_hello_world));
}
void swModule_destory(swModule *module)
{
PHP::destory();
}
//C++函数的实现
void cpp_hello_world(Args &args, Variant &retval)
{
printf("SWOOLE_BASE=%ld\n", PHP::constant("SWOOLE_BASE").toInt());
printf("swoole_table::TYPE_INT=%ld\n", PHP::constant("swoole_table::TYPE_INT").toInt());
Variant argv = args.toArray();
var_dump(argv);
Array arr(retval);
arr.set("key", "key");
arr.set("value", 12345);
}
- PHP_API.hpp和module.h在Swoole包中
- swModule_init表示模块初始化函数
- swModule_destory是模块销毁函数
- cpp_hello_world就是我们编写的C++扩展函数,在PHP代码中可以调用
cpp_hello_world()
来执行 - 在swModule_init中调用了
PHP::registerFunction
注册C++函数到PHP中
程序逻辑
cpp_hello_world
函数中的代码逻辑比较简单,首先cpp_hello_world函数一共2个参数,argv表示传入的参数,retval是给PHP的返回值。
在代码中可以直接使用数组的方式访问参数,如下:
void cpp_hello_world(Args &args, Variant &retval)
{
int a = argv[0].toInt();
string b = argv[1].toString();
double c = argv[2].toFloat();
}
使用var_dump函数可以打印PHP变量的值。
Variant d = argv[3];
var_dump(d);
返回值可以直接赋值。
retval = 1234;
retval = "hello world";
可以使用Array类实现数组操作。
//将返回值转为数组
Array arr(retval);
arr.set("key", 123);
arr.set("value", "world");
编译程序
编写Makefile
SWOOLE_SRC = "/home/htf/workspace/swoole"
PHP_INCLUDE = `php-config --includes`
PHP_LIBS = `php-config --libs`
PHP_LDFLAGS = `php-config --ldflags`
all: test.cpp
c++ -DHAVE_CONFIG_H -g -o test.so -O0 -fPIC -shared test.cpp ${PHP_INCLUDE} -std=c++11 -I${SWOOLE_SRC}/include -I${SWOOLE_SRC}
clean: test.so
rm test.so
编译模块
make
编译完成后,会生成一个test.so
,可以使用swoole_load_module
方法来加载模块
运行程序
$module = swoole_load_module(__DIR__.'/test.so');
cpp_hello_world(1234, "hello", 3.1415, array("xxx", "eeee"));
$module->destory();