如何转换C ++ map <string,map <string>&gt; PHPCPP库中的Php :: Value?

时间:2017-08-10 11:55:29

标签: c++ php-cpp

我正在使用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 &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

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;
    }
}