【问题标题】:PHP Curl request does not work outside of Postman environment - formdata containing arrayPHP Curl 请求在 Postman 环境之外不起作用 - formdata 包含数组
【发布时间】:2018-11-05 04:54:02
【问题描述】:

使用以下代码:

 $curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://www.sample.com/v2/clients?token=DMfJjzWLngIn0JBHA0gWcg",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"active_registration_id\"\r\n\r\n123\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"language_id\"\r\n\r\n79\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"archived\"\r\n\r\n{{archived}}\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"enabled\"\r\n\r\n{{enabled}}\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"password\"\r\n\r\nSamplePassword\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"password_confirmation\"\r\n\r\nSamplePassword\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"registration_attributes[first_name]\"\r\n\r\nJustin\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"registration_attributes[last_name]\"\r\n\r\nTrudeau\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"registration_attributes[email]\"\r\n\r\nemail@sample.com\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"registration_attributes[telephone_1]\"\r\n\r\n555-555-5555\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"registration_attributes[date_of_birth]\"\r\n\r\n1943-10-10\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"registration_attributes[gender]\"\r\n\r\nMale\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"registration_attributes[referral_code]\"\r\n\r\nAmple Clinic 123\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"registration_attributes[status]\"\r\n\r\nRegistration Pending\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"For Additional Permitted Parameters:\"\r\n\r\nSee Registration Parameters\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"registration_attributes[date_of_birth]\"\r\n\r\n1943-10-10\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"registration_attributes[gender]\"\r\n\r\nMale\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"registration_attributes[referral_code]\"\r\n\r\nAmple Clinic 123\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"registration_attributes[status]\"\r\n\r\nRegistration Pending\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; ",
  CURLOPT_HTTPHEADER => array(
    "Content-Type: application/x-www-form-urlencoded",
    "content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}</pre>

我收到响应 {"registration_attributes":["Missing"]} 此代码将在 Postman 中运行,但在生产服务器上不起作用。我创建registration_attributes数组的方式有什么问题吗?

【问题讨论】:

  • 有一个http_build_query() 函数可以用来代替发送原始请求
  • content-type: multipart/form-data;你是通过curl上传文件吗?
  • 所以我应该构建一个包含主表单数据和注册属性数组的数组,并在将其添加到 CURLOPT_POSTFIELDS 行之前对其使用 http_build_query() 函数?您认为 Postman 和输出的请求之间存在什么差异?
  • 您也可以将数组传递给 postfield。至于差异,我怀疑你错过了最后一个边界。您可以搜索原始形式的 multipart/form-data 以及边界的工作方式
  • 没有文件上传,我试过删除
    content-type: multipart/form-data; 
    但我仍然得到相同的结果

标签: php curl postman


【解决方案1】:

您的 CURLOPT_POSTFIELDS 字符串看起来不完整,已被切断,但这无论如何都是在 PHP 中执行 multipart/form-data 请求的糟糕方式,让 php/libcurl 创建 multipart/form-data 请求要容易得多为你。在你的情况下看起来像

curl_setopt ( $ch, CURLOPT_POSTFIELDS, array (
        "active_registration_id" => 123,
        "language_id" => 79,
        "archived" => "{{archived}}",
        "enabled" => "{{enabled}}",
        "password" => "SamplePassword",
        "password_confirmation" => "SamplePassword",
        "registration_attributes" => array (
                "first_name" => "Justin",
                "last_name" => "Trudeau",
                "email" => "email@sample.com",
                "telephone_1" => "555-555-5555",
                "date_of_birth" => "1943-10-10",
                "gender" => "male",
                "referral_code" => "Ample Clinic 123",
                "Status" => "Registration Pending" 
        ),
        "For Additional Permitted Parameters:" => "See Registration Parameters", 
        // ...
) );

出于不同的原因,去掉这两个标题:"Content-Type: application/x-www-form-urlencoded" - 这个标题在撒谎,它不是 x-www-form-urlencoded 格式,它是一种完全不兼容的“multipart/form-data”格式。 "content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" - curl 将自动设置此标头,并使用不同的(随机生成的)边界,如果您手动设置边界,服务器将无法解析它。 (因为 headers 中指定的边界会出错)

【讨论】:

  • 好的,谢谢。文档指定标头应为 application/x-www-form-urlencoded。正如我在上面的 cmets 中提到的,删除标头并更改为数组仍然返回相同的错误。我认为它返回 {"registration_attributes":["Missing"]} 无论为 CURLOPT_POSTFIELDS 设置什么,所以我认为由于标题要求冲突,它甚至没有获取任何表单数据
  • @JeremyGiles 哦,如果你真的应该使用application/x-www-form-urlencoded 格式,那么你原来的 CUROPT_POSTFIELDS 数组仍然是完全错误的(因为这是一个硬编码的 multpart/form-data 请求,而不是urlencoded 请求),要使用 application/x-www-form-urlencoded 格式,使用 http_build_query 函数和我上面发布的数组,curl_setopt ( $ch, CURLOPT_POSTFIELDS, http_build_query(array ( "active_registration_id" =&gt; 123,...))); - 再次,不要手动设置内容类型标题, curl 会为你做的。
猜你喜欢
  • 2018-11-04
  • 2018-03-04
  • 2023-04-06
  • 2017-10-18
  • 1970-01-01
  • 2019-04-08
  • 2013-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多