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#include #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();