如何在PHPCPP库中将C++map<string,map<string>>转换为php::value?

How to convert C++ map<string,map<string>> to Php::Value in PHPCPP library?

本文关键字:gt lt string 转换 php PHPCPP value map C++map      更新时间:2023-10-16

我正在使用PHP库创建PHP扩展,并且C++函数返回的映射变量转换为PHPCPPPhp::Value时遇到困难。我这样做的原因是从用C++编写的函数中获取多维关联数组结果。

有没有办法在PHPPPP中将C++map < string, map < double, map < double, map< double, map< string, map< int, double>>>>>> data转换为Php::Value,或者有更好的方法来解决这个问题?

这是我C++代码:

#include <phpcpp.h>
#include <ctime>
#include <iostream>
#include <map>
#include <algorithm>
#include <string> 
#include <regex>
#include <stdlib.h>     /* atof,strtod */
#include <cstddef>        // std::size_t
#include <sstream>
#include <vector>
#include <boost/algorithm/string.hpp> // include Boost, a C++ library
#include <boost/regex.hpp>
using namespace std;

double get_curve_rate(string curve_type, double shape, double peak, double tpeak, double lag, string start, string index, double interval) {
double rate = 0.0;
if (curve_type == "t1") {
if ((shape + peak + tpeak) != 0)
rate = 0;
}
else if (curve_type == "t2") {
if ((peak + tpeak + lag) != 0)
rate = 1;
}
return  rate;
}
class Curve : public Php::Base
{
public :
string type;
double shape = 0.0;
double peak = 0.0;
double tpeak = 0.0;
double lag = 0.0;
string start;
double interval = 0.0;
int month_no = 0;
string month;
string start_date;
/**
*  C++ constructor and destructor
*/
Curve() {}
virtual ~Curve() {}

};
Php::Value get_all_curve_rates(Php::Parameters &params) {
vector<Curve> curves = params[0];
//create an associative array and return to php
map< string, map<double, map<double, map<double, map<string, map<int, double>>>>>> data;
for (auto &c : curves) // access by reference to avoid copying
{
if (c.type == "t1"){}
//      data[c.type][c.peak][c.tpeak][c.lag][c.start_date][c.month_no] = get_curve_rate(c.type, c.shape, c.peak, c.tpeak, c.lag, c.start, c.month, c.interval);
else if (c.type == "t2") {}
//      data[c.type][c.shape][c.peak][c.tpeak][c.start_date][c.month_no] = get_curve_rate(c.type, c.shape, c.peak, c.tpeak, c.lag, c.start, c.month, c.interval);
}

return data;
}
/**
*  Switch to C context, because the Zend engine expects get get_module()
*  to have a C style function signature
*/
extern "C" {
/**
*  Startup function that is automatically called by the Zend engine
*  when PHP starts, and that should return the extension details
*  @return void*
*/
PHPCPP_EXPORT void *get_module()
{
// the extension object
static Php::Extension extension("test", "1.0");
// add functions so that they can be called from PHP scripts
// description of the class so that PHP knows which methods are accessible
Php::Class<Curve> curve("Curve");

extension.add("get_all_curve_rates", get_all_curve_rates, {
Php::ByVal("curves", Php::Type::Array),
});
// return the extension details
return extension;
}
} 

编译器给出以下错误:

In file included from /usr/include/phpcpp.h:42:0,
from main.cpp:1:
/usr/include/phpcpp/value.h: In instantiation of ‘Php::Value::Value(const std::map<std::basic_string<char>, T>&) [with T = std::map<double, std::map<double, std::map<double, std::map<std::basic_string<char>, std::map<int, double> > > > >]’:
main.cpp:428:9:   required from here
/usr/include/phpcpp/value.h:113:34: error: no matching function for call to ‘Php::Value::setRaw(const char*, std::basic_string<char>::size_type, const std::map<double, std::map<double, std::map<double, std::map<std::basic_string<char>, std::map<int, double> > > > >&)’
for (auto &iter : value) setRaw(iter.first.c_str(), iter.first.size(), iter.second);
^~~~~~
In file included from /usr/include/phpcpp.h:42:0,
from main.cpp:1:
/usr/include/phpcpp/value.h:1165:10: note: candidate: void Php::Value::setRaw(int, const Php::Value&)
void setRaw(int index, const Value &value);
^~~~~~
/usr/include/phpcpp/value.h:1165:10: note:   candidate expects 2 arguments, 3 provided
/usr/include/phpcpp/value.h:1176:10: note: candidate: void Php::Value::setRaw(const char*, int, const Php::Value&)
void setRaw(const char *key, int size, const Value &value);
^~~~~~
/usr/include/phpcpp/value.h:1176:10: note:   no known conversion for argument 3 from ‘const std::map<double, std::map<double, std::map<double, std::map<std::basic_string<char>, std::map<int, double> > > > >’ to ‘const Php::Value&’
In file included from /usr/include/phpcpp.h:42:0,
from main.cpp:1:
/usr/include/phpcpp/value.h: In instantiation of ‘std::vector<T> Php::Value::vectorValue() const [with T = Curve]’:
/usr/include/phpcpp/value.h:723:30:   required from ‘Php::Value::operator std::vector<T>() const [with T = Curve]’
main.cpp:414:33:   required from here
/usr/include/phpcpp/value.h:483:13: error: no matching function for call to ‘std::vector<Curve>::push_back(Php::Value)’
result.push_back(get(i));
^~~~~~
In file included from /opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/vector:64:0,
from /usr/include/phpcpp.h:19,
from main.cpp:1:
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/stl_vector.h:914:7: note: candidate: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Curve; _Alloc = std::allocator<Curve>; std::vector<_Tp, _Alloc>::value_type = Curve]
push_back(const value_type& __x)
^~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/stl_vector.h:914:7: note:   no known conversion for argument 1 from ‘Php::Value’ to ‘const value_type& {aka const Curve&}’
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/stl_vector.h:932:7: note: candidate: void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = Curve; _Alloc = std::allocator<Curve>; std::vector<_Tp, _Alloc>::value_type = Curve]
push_back(value_type&& __x)
^~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/stl_vector.h:932:7: note:   no known conversion for argument 1 from ‘Php::Value’ to ‘std::vector<Curve>::value_type&& {aka Curve&&}’
make: *** [main.o] Error 1

有什么建议可以解决这些错误吗?

更新尝试通过修改C++来实现下面建议的 Caleth 示例:

class Curve : public Php::Base
{
public :
string type;
double shape = 0.0;
double peak = 0.0;
double tpeak = 0.0;
double lag = 0.0;
string start;
double interval = 0.0;
int month_no = 0;
string month;
string start_date;
/**
*  C++ constructor and destructor
*/
//Curve() {}
//virtual ~Curve() {}
Curve(Php::Value value) :
type(value["type"]),
shape(value["shape"]),
peak(value["peak"]),
tpeak(value["tpeak"]),
lag(value["lag"]),
interval(value["interval"]),
month_no(value["month_no"]),
month(value["month"]),
start_date(value["start_date"])
{}
operator Php::Value() const
{
Php::Value value;
value["type"] = type;
value["shape"] = shape;
value["peak"] = peak;
value["tpeak"] = tpeak;
value["lag"] = lag;
value["interval"] = interval;
value["month_no"] = month_no;
value["month"] = month;
value["start_date"] = start_date;
return value;
}
};

Php::Value get_all_curve_rates(Php::Parameters &params) {
vector<Php::Value> curves = params[0];
Php::Value data;
for (auto &c : curves) // access by reference to avoid copying
{
Curve curv = c;
if (curv.type == "t1")
data[curv.type][curv.peak][curv.tpeak][curv.lag][curv.start_date][curv.month_no] = 2.0;//get_curve_rate(curv.type, curv.shape, curv.peak, curv.tpeak, curv.lag, curv.start, curv.month, curv.interval);
else if (curv.type == "t2")
data[curv.type][curv.shape][curv.peak][curv.tpeak][curv.start_date][curv.month_no] = 1.0;//get_curve_rate(curv.type, curv.shape, curv.peak, curv.tpeak, curv.lag, curv.start, curv.month, curv.interval);
}

return data;
}
/**
*  Switch to C context, because the Zend engine expects get get_module()
*  to have a C style function signature
*/
extern "C" {
/**
*  Startup function that is automatically called by the Zend engine
*  when PHP starts, and that should return the extension details
*  @return void*
*/
PHPCPP_EXPORT void *get_module()
{
// the extension object
static Php::Extension extension("test", "1.0");
// add functions so that they can be called from PHP scripts
// description of the class so that PHP knows which methods are accessible
Php::Class<Curve> curve("Curve");
extension.add("get_all_curve_rates", get_all_curve_rates, {
Php::ByVal("Curve", Php::Type::Array),
});
// return the extension details
return extension;
}
}

但是现在还有其他错误:

/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:3010:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
^~~~~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:2975:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const basic_string& __str);
^~~~~~~~~~~~
main.cpp:417:33: error: call of overloaded ‘basic_string(Php::HashMember<std::basic_string<char> >)’ is ambiguous
start_date(value["start_date"])
^
In file included from /opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/string:52:0,
from /usr/include/phpcpp.h:17,
from main.cpp:1:
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:3027:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(basic_string&& __str)
^~~~~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:3010:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
^~~~~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:2975:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const basic_string& __str);
^~~~~~~~~~~~
main.cpp:417:33: error: call of overloaded ‘basic_string(Php::HashMember<std::basic_string<char> >)’ is ambiguous
start_date(value["start_date"])
^
In file included from /opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/string:52:0,
from /usr/include/phpcpp.h:17,
from main.cpp:1:
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:3027:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(basic_string&& __str)
^~~~~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:3010:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
^~~~~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.2.1/bits/basic_string.h:2975:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string(const basic_string& __str);
^~~~~~~~~~~~
make: *** [main.o] Error 1

您需要提供一种将Php::Values 转换为Curves 的方法。 查看文档,这通常是在课堂上完成的。

class Curve : public Php::Base
{
public :
string type;
double shape = 0.0;
double peak = 0.0;
double tpeak = 0.0;
double lag = 0.0;
string start;
double interval = 0.0;
int month_no = 0;
string month;
string start_date;
Curve(Php::Value value)
: type(value["type"]), 
shape(value["shape"]),
// etc... 
{}
operator Php::Value() const 
{
Php::Value value;
value["type"] = type;
value["shape"] = shape;
// etc...
return value;
}
}