将Python请求转换为PHP-cURL等效代码

0 投票
3 回答
3371 浏览
提问于 2025-04-16 06:19

我正在向一个网址发送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错误)

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中,我使用的是字典列表;而在PHP中,我觉得应该是数组的数组。

3 个回答

1

我不确定这是否会导致你的问题,但我注意到两者之间有个区别:在你发送的Python代码中,有两行头信息:Content-Type和Accept。而在PHP代码中,它们合并成了一行。

1

你缺少了参数索引 - cURL 的 POST 字段需要以查询字符串或数组的形式发送。

可以这样做:

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

或者这样:

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

payload 替换成 API 期望用来接收 JSON 字符串的参数名称。

如果这个 API 接口不需要某个参数,那就可以正常工作 - 只是它不会出现在你测试脚本中的 POST 数组里。你可以使用

$data = file_get_contents("php://input");
var_dump($data);

来获取 POST 内容的主体。

1

在这种情况下,我发现直接查看数据传输的内容总比费劲去猜测代码哪里出错要好。

我的建议是:

  • 用 Python 的 BaseHTTPServer 创建一个小测试服务器,并从 BaseHTTPRequestHandler 继承一个类,这个类只需要重写 do_POST 方法,不做其他事情。

  • 你的 do_POST 方法应该把接收到的头信息和 POST 请求的内容保存到文件里。

  • 把你的代码指向这个小测试服务器,然后对比它生成的文件。如果问题不容易发现,至少你会得到一个或多个有用的线索,帮助你解决这个问题。

撰写回答