Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/235.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP与Golang http调用得到不同的结果_Php_Google App Engine_Go_Difference - Fatal编程技术网

PHP与Golang http调用得到不同的结果

PHP与Golang http调用得到不同的结果,php,google-app-engine,go,difference,Php,Google App Engine,Go,Difference,我试图在Google App Engine Go中实现以下PHP代码: <?php function api_query(array $req = array()) { $key = '90294318da0162b082c3d27126be80c3873955f9'; $req['method'] = 'getinfo'; $req['nonce'] = 1394503747386411; // generate th

我试图在Google App Engine Go中实现以下PHP代码:

<?php

function api_query(array $req = array()) {
        $key = '90294318da0162b082c3d27126be80c3873955f9';

        $req['method'] = 'getinfo';
        $req['nonce'] = 1394503747386411;

        // generate the POST data string
        $post_data = http_build_query($req, '', '&');
        $sign = '75da1e3ff750286bf73d03197f1b779fbfff963fd7402941ae326509a6615eacb839b44f236b4d5ee6cff39321e7b35e9563a9a2075e99df0f4ee3b732999348';

        // generate the extra headers
        $headers = array(
                'Sign: '.$sign,
                'Key: '.$key,
        );

        // our curl handle (initialize if required)
        static $ch = null;
        if (is_null($ch)) {
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; Cryptsy API PHP client; '.php_uname('s').'; PHP/'.phpversion().')');
        }
        curl_setopt($ch, CURLOPT_URL, 'https://api.cryptsy.com/api');
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

        // run the query
        $res = curl_exec($ch);

        if ($res === false) throw new Exception('Could not get reply: '.curl_error($ch));
        $dec = json_decode($res, true);
        if (!$dec) throw new Exception('Invalid data received, please make sure connection is working and requested API exists');

        echo "<pre>".print_r($dec, true)."</pre>";
        return $dec;
}

api_query();

我收到一个错误,说“无法授权请求-检查您的帖子数据”。有人知道是什么导致了这个错误吗?目前我最好的猜测是,Go中的请求头可能是一个map[string][]字符串,而在PHP中它似乎是一个数组…

正如LeGEC所建议的,您将
POST
数据放在URL的末尾,就好像它是一个
GET
请求一样

试着替换

data := struct {
    method string
    nonce  string
}{
    "getinfo",
    "1394503747386411",
}
signature := "75da1e3ff750286bf73d03197f1b779fbfff963fd7402941ae326509a6615eacb839b44f236b4d5ee6cff39321e7b35e9563a9a2075e99df0f4ee3b732999348"
postData, err := json.Marshal(data)
if err != nil {
    return nil, err
}
buf := bytes.NewBuffer(postData)
req, err := http.Post(AuthAPI, "application/json", buf)


这是你需要的,这是你错过的一些东西

  • 使用
    https
    时,需要设置
    TLSClientConfig
  • 自定义标题中缺少
    X-
    前缀
  • values.Encode()
    的位置错误
示例:参见


从未使用过golang,但马上我就可以看到
符号:&Key:
上的标题不同,请
转到fmt
您的代码,并为超出范围的变量提供值。另外,代码的哪一部分会打印错误?@LozCherone我认为添加了
,因为在PHP中头是一个数组,所以要使它们成为一个类似于映射的结构,需要添加
,而在Go中它们已经是一个映射,因此可以正确打印。@AntoineG我以前忘记添加AuthAPI,但现在我把它放进去了。我认为没有任何其他变量超出范围。代码本身没有打印错误,只是我调用的服务返回了一个错误,这意味着PHP和Go之间调用的方式有所不同。POST数据应该写入请求体中。在Go代码中,它们作为GET参数添加到url.Hmm中,执行http.Post意味着在执行请求之前无法设置http头。我尝试在我的代码中添加缓冲区,但仍然得到了相同的响应…好吧,在仔细研究了各种方法之后,结果发现我向URL添加值的方式是问题之一。嗯,我认为这将是vanilla golang的一种方法,非GAE Go。您所说的
非GAE
是什么意思?有没有更好的方法使用
http.Post
设置标题?在GAE中,您不运行
main
函数,并且不使用
urlfetch
就不能进行http调用,这需要
appengine.Context
values := url.Values{}
values.Set("method", "getinfo")
values.Set("nonce", "1394503747386411")

signature := "75da1e3ff750286bf73d03197f1b779fbfff963fd7402941ae326509a6615eacb839b44f236b4d5ee6cff39321e7b35e9563a9a2075e99df0f4ee3b732999348"

req, err := http.NewRequest("POST", AuthAPI+"?"+values.Encode(), nil)
data := struct {
    method string
    nonce  string
}{
    "getinfo",
    "1394503747386411",
}
signature := "75da1e3ff750286bf73d03197f1b779fbfff963fd7402941ae326509a6615eacb839b44f236b4d5ee6cff39321e7b35e9563a9a2075e99df0f4ee3b732999348"
postData, err := json.Marshal(data)
if err != nil {
    return nil, err
}
buf := bytes.NewBuffer(postData)
req, err := http.Post(AuthAPI, "application/json", buf)
var (
    urlStr = "https://api.cryptsy.com/api"
    key    = "YOUR KEY"
    secret = "YOUR SECRECT"
    agent  = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
)

func main() {

    client := &http.Client{Transport: &http.Transport{
        TLSClientConfig: &tls.Config{
            InsecureSkipVerify: true,
        },
    }}

    values := url.Values{}
    //  $req['method'] = $method;
    values.Set("method", "getinfo")

    // $mt = explode(' ', microtime());
    // $req['nonce'] = $mt[1];
    values.Set("nonce", time.Nanosecond.String())

    //  $post_data = http_build_query($req, '', '&');
    encoded := values.Encode()

    mac := hmac.New(sha512.New, []byte(secret))
    mac.Write([]byte(encoded))

    //$sign = hash_hmac("sha512", $post_data, $secret);
    sign := fmt.Sprintf("%x", mac.Sum(nil))

    req, err := http.NewRequest("POST", urlStr, bytes.NewBufferString(encoded))

    if err != nil {
        log.Fatalln(err)
    }

    // generate the extra headers
    // $headers = array(
    // 'Sign: '.$sign,
    // 'Key: '.$key,
    // );
    req.Header.Set("X-Sign", sign)
    req.Header.Set("X-Key", key)

    //  curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; Cryptsy API PHP client; '.php_uname('s').'; PHP/'.phpversion().')');
    req.Header.Set("User-Agent", agent)
    req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Add("Content-Length", strconv.Itoa(len(encoded)))

    //       $res = curl_exec($ch);
    resp, err := client.Do(req)

    if err != nil {
        log.Fatalln(err)
    }
    fmt.Println(resp.Status)

    data, _ := ioutil.ReadAll(resp.Body)
    fmt.Printf("%s", data)
}