基于 Swoole 开发 PHP 扩展

1,180 阅读2分钟
原文链接: my.oschina.net

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