Swoole C++ 扩展已支持 php-fpm 环境 - matyhtf

729 阅读2分钟
原文链接: my.oschina.net

今天对Swoole的C++扩展模块做了2项改进。

函数调用优化

现在在C++模块中可以直接传参调用PHP的函数和对象方法了。不再需要使用Array来做中介容器。

调用PHP函数:

exec("test", "hello world", 1234, 12345.678, false);

调用PHP的test函数,一共传入了4个不同的参数,注意如果函数不存在将会报致命错误

调用对象方法:

Object redis = PHP::create("redis");
auto ret1 = redis.exec("connect", "127.0.0.1", 6379);
auto ret2 = redis.exec("get", "key");
printf("value=%s\n", ret2.toCString());

这个程序连接了Redis服务器,并执行get从Redis服务器中获取了一个Key为"key"的数据。C++函数中只用了几行代码就实现了像PHP代码一样的功能。大大简化了开发的工作。

启动自动加载模块

现在C++模块可以配置到php.ini在swoole扩展初始化时就加载到PHP中。现在C++扩展模块提供的函数和类可以支持在php-fpm和cli等环境中调用。

目录结构

/stdext.cpp #C++源文件
/Makefile #make编译配置文件

编写代码

#include <string>
#include <iostream>

#include "PHP_API.hpp"
#include "swoole.h"
#include "module.h"

using namespace std;
using namespace PHP;

extern "C"
{
    int swModule_init(swModule *);
    void swModule_destory(swModule *);
}

void String_construct(Object &_this, Args &args, Variant &retval)
{
    _this.set("string", args[0].toString());
}

int swModule_init(swModule *module)
{
    module->name = (char *) "stdext";

    Class *c = new Class("Spl\\String");
    c->addMethod("__construct", String_construct, CONSTRUCT);
    c->addProperty("string", "");
    PHP::registerClass(c);
    return SW_OK;
}

void swModule_destory(swModule *module)
{
    PHP::destory();
}

编译

Makefile文件:

SWOOLE_SRC = "/home/htf/workspace/swoole"
PHP_INCLUDE = `php-config --includes`
PHP_LIBS = `php-config --libs`
PHP_LDFLAGS = `php-config --ldflags`
PHP_EXTENSION_DIR = `php-config --extension-dir`

all: stdext.cpp
    c++ -DHAVE_CONFIG_H -g -o stdext.so -O2 -fPIC -shared stdext.cpp ${PHP_INCLUDE} -std=c++11 -I${SWOOLE_SRC}/include -I${SWOOLE_SRC}
clean: stdext.so
    rm stdext.so
install: stdext.so
    cp stdext.so ${PHP_EXTENSION_DIR}

编译安装:

make install

编译好的stdext.so会自动安装到PHP的扩展路径。但它不是一个PHP扩展而是Swoole的C++模块,需要配置php.ini,增加配置,并重启php-fpm即可。

swoole.modules = "stdext.so, test.so"

加载多个C++扩展模块时,需要使用逗号分割

执行程序

<?php
$r = new Spl\String("hello world");
var_dump($r);

可以将此脚本放到php-fpm网站的目录中,用浏览器访问。也可以直接使用php命令行来执行。