我正在使用PHP库创建PHP扩展,我很难将C ++映射变量转换为函数返回的PHPCPP Php::Value
。我这样做的原因是从用C ++编写的函数中获得多维关联数组结果。
有没有办法在PHPCPP中将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 ¶ms) {
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 ¶ms) {
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
答案 0 :(得分:0)
您需要提供一种将Php::Value
转换为Curve
的方法。查看the docs,这通常是在课堂上完成的。
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;
}
}