【问题标题】:convert python request to PHP-cURL equivalent将 python 请求转换为等效的 PHP-cURL
【发布时间】:2010-10-30 11:07:28
【问题描述】:

我正在向 URL 发送 POST 请求。它在 python 中可以正常工作,但在 php-curl 中,我总是收到一个错误的请求错误(即我的 POST 数据与服务器预期的不一样)

Python 代码:(正常工作。200 OK)

import httplib, urllib, json

def SendRequest(param1):
    url = "api.xyz.com"
    body = {"version": "1.0", "data":[{"param1":param1, "age":35}]}
    jsonBody = json.dumps(body)

    headers = {"Content-type": "application/json",
               "Accept": "application/json; charset=utf8"}
    conn = httplib.HTTPConnection(url)
    conn.request("POST", "/api/?client_id=xx-xx-xx", jsonBody, headers)
    response = conn.getresponse()

php-cURL 代码(不起作用。406 Bad request error)

function sendCurlRequest($param1)
{
    $payload = preparePayload($param1); 
    $url = "http://api.xyz.com/api/?client_id=xx-xx-xx"; 
    $jsonResponse = executePOSTRequest($url, $payload);
    $response = json_decode($jsonResponse);
}

function preparePayload($param1)
{
    $payload = array("version" = "1.0",
                     "data" => array(array("param1" => $param1,
                                           "age" => 35
                                          )
                                    ),
                    );

    $jsonPayload = json_encode($payload);
    return $jsonPayload;
}

function executePOSTRequest($url, $payload)
{
    $newlines = array("\r", "\n", " ");
    $url = str_replace($newlines, '', $url);
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt ($ch, CURLOPT_HTTPHEADERS,array('Content-Type:application/json; Accept: application/json; charset=utf8'));

    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $result = curl_exec($ch);
}

我知道我在使用 cURL 时存在一些错误。请提出建议。

更新:在 php 中使用双精度数组是因为服务器需要这种格式的 JSON 字符串(POST 有效负载)

{
"version": "1.0",
"data":
[{"param1":name, "age":35},{"param1":name,"age":60}]
}

在 python 中,我使用的是 dict 列表;在 php 中我认为它只是数组的数组。

【问题讨论】:

  • 我很确定您的问题是原始 Python 代码发送的是纯 JSON 正文,而 PHP 版本将各种值作为 POST 字段发布。我不知道如何发送纯 JSON 正文,但我确信答案就在 SO
  • Pekka,感谢您的评论,但我认为在这两种情况下,我都会发送一个 JSON 字符串作为 POST 数据。你的意思是在 php 中,我的 JSON 字符串被分成几块,每个字段都作为表单字段发送?事实并非如此。

标签: php python curl


【解决方案1】:

在这种情况下,我发现最好还是查看一下线路上的内容,而不是试图弄清楚代码可能有什么问题。

我的建议:

  • 使用 python BaseHTTPServer 和 派生出一个类 BaseHTTPRequestHandler 没有 做任何事情,但提供覆盖 do_POST 的方法

  • 你的do_POST 应该只是转储 它接收到的标头和 POST 正文 文件

  • 将您的代码示例指向此 小测试服务器,然后比较 它创建的文件。我正在猜测 如果答案不是立即 很明显,你至少会得到 一个或多个有用的跺脚线索 这个问题解决了。

【讨论】:

  • 感谢您的中肯建议。对以后的问题也有很大的帮助。最后,我通过 php 和 python 对本地服务器进行了 POST,并比较了标头和数据的差异。我在使用 curl 时犯了一些错误。谢谢。
  • 太棒了!很高兴能够提供帮助。
【解决方案2】:

我不确定这是否会导致您的问题,但我确实看到了两者之间的区别: 在 python 代码中,您发送两个标题行:Content-Type 和 Accept。在 PHP 代码中,它们是一行。

【讨论】:

  • 不,这不会导致问题。我与 curl 搏斗了很长时间。我尝试将 Content-Type 和 Accept 作为两个单独的行发送。没有区别。
  • 好的,您是否也知道该选项应命名为:CURLOPT_HTTPHEADER,末尾不带 S?所以: curl_setopt ($ch, CURLOPT_HTTPHEADER,array('Content-Type:application/json;','Accept: application/json; charset=utf8'));
  • 嘿,Michielvv,不错的收获。我没有注意到额外的“S”。当我对本地服务器进行 POST 时,我才在 apache 错误日志中看到它。谢谢。 :-) 另外,正如您所说, Content-Type 和 Accept 应该是数组中的不同元素。将它们合并为一行是错误的。谢谢。
【解决方案3】:

您缺少参数索引 - cURL POST 字段需要作为查询字符串或数组发送。

要么:

curl_setopt($ch, CURLOPT_POSTFIELDS, 'payload=' . urlencode($payload));

或者

curl_setopt($ch, CURLOPT_POSTFIELDS, array('payload' => $payload));

payload 替换为 API 期望保存 JSON 字符串的参数名称。

如果端点 API 不需要参数,那么它应该可以工作 - 它只是不会出现在测试脚本的 POST 数组中。您可以使用

获取 POST 内容的正文
$data = file_get_contents("php://input");
var_dump($data);

【讨论】:

  • 是的,我明白你的意思。但是在 python 中,我没有使用任何参数来保存 JSON 字符串。此外,API 文档没有提及任何此类参数。它提到的只是“将请求格式化为 JSON 字符串并将其作为 POST 数据提交到给定的 URL”。这是 cURL 限制吗?
  • 在这种情况下,它应该像你之前写的那样工作。您是使用实际的 API 还是仅使用测试脚本进行尝试?我为您添加了一种使用 $_POST 数组测试直接 POST 内容的方法
  • 是的,伊兰。谢谢。我按照 bgporter 的建议通过 php 和 python 在本地服务器上发布并检查两者之间的区别。这就是我遇到空 _POST 问题的方式。 stackoverflow.com/questions/4060345/post-is-empty-in-php
  • 我的 API 现在工作正常。我正在通过 get_header($url, 1) php函数检查响应标头。它总是返回 406 错误。正确的方法是使用“curl_getinfo($ch)”。它给出了 200 确定。另一个错误是 Michielvv 指出的。 (使用 CURLOPT_HTTPHEADER 而不是 HEADERS :))
猜你喜欢
  • 2017-08-03
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 2017-04-12
  • 2015-10-25
  • 2016-01-30
  • 2020-03-18
相关资源
最近更新 更多