今天对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
命令行来执行。