【问题标题】:Not passing CSV file in cURL POST correctly in PHP未在 PHP 中正确传递 cURL POST 中的 CSV 文件
【发布时间】:2017-07-11 17:17:45
【问题描述】:

我正在尝试向 API 发送 POST 请求,并且该请求的一部分我正在添加一个 CSV 文件以根据我提供的电子邮件和号码获取返回令牌。前几行代码使用了我从数据库中检索到的数据,并且生成文件并用文本数据填充它是正确的。问题出在我的 cURL 上。当我在 PostMan 中发出这个请求时,结果非常好,我实际上是使用 PostMan 的 PHP-curl 生成的代码来编写这个请求的。但是,这条线

filename=\"".$filename."\"\r\n 

由于某种原因,不会调出之前刚刚正确填充的文件,并且 API 日志说该文件中没有数据。这两个文件都位于同一个目录中,所以我真的对自己做错了什么感到茫然。

$file = fopen($filename, "w");

while ($row2 = mysqli_fetch_array($query2)){
    $txt = "$row2[email], $row2[firstname], $row2[lastname], 
    $row[company], $row2[mobilephone]\n";
    echo $txt;
    fwrite($file, $txt);
}

$curl = curl_init();

echo $filename."\n";

curl_setopt_array($curl, array(
    CURLOPT_URL => "https://example.com",
    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\n
        Content-Disposition: form-data; 
        name=\"token\"\r\n\r\12345\r\n
        ------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n
        Content-Disposition: form-data; name=\"datafile\";
        filename=\"".$filename."\"\r\n
        Content-Type: text/csv\r\n\r\n\r\n
        ------WebKitFormBoundary7MA4YWxkTrZu0gW--",
    CURLOPT_HTTPHEADER => array(
        "cache-control: no-cache",
        "content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
    ),
));

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

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

谁能发现我在这里做错了什么?

注意:出于隐私/安全原因,我用虚拟数据替换了几个字段和字符串

【问题讨论】:

  • 您传递字符串而不是数组或 json 的任何原因?
  • 在他们的应用程序中成功创建调用后,我只是使用 Postman 生成的 PHP-curl 代码

标签: php csv curl post


【解决方案1】:

我想不出任何(理智的)理由来手动进行multipart/form-data-encoding,而让 curl 为您编码它是微不足道的。整个 curl_setopt_array 可以替换为

curl_setopt_array ( $curl, array (
        CURLOPT_URL => "https://example.com",
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => "",
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_POST=>true,
        CURLOPT_POSTFIELDS => array (
                'token' => '12345',
                'datafile' => new CURLFile ( $filename, 'text/csv', 'datafile' ) 
        ),
        CURLOPT_HTTPHEADER => array (
                "cache-control: no-cache" 
        ) 
) );
  • curl 将为您进行多部分/表单数据编码。

【讨论】:

    【解决方案2】:

    API 日志显示文件中没有数据

    原因是您告诉您将在查询中发送“filename.txt”,但实际上并未发送数据。

    例如,如果您发送filename.txt||test|| 内容并带有POST 查询,结果查询将是这样的:

    ------WebKitFormBoundaryWJ0Ly0MV6I2Kvqwe
    Content-Disposition: form-data; name="token"
    
    12345
    ------WebKitFormBoundaryWJ0Ly0MV6I2Kvqwe
    Content-Disposition: form-data; name="datafile"; filename="filename.txt"
    Content-Type: text/plain
    
    ||test||
    ------WebKitFormBoundaryWJ0Ly0MV6I2Kvqwe--
    

    如您所见,文件的内容应该添加到查询中。在您的查询中,只有声明,名称为 $filename 的文件将被发送,其内容将稍后发送,但根本没有内容:

    ------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n
            Content-Disposition: form-data; name=\"datafile\";
            filename=\"".$filename."\"\r\n
            Content-Type: text/csv\r\n\r\n\r\n
    

    所以服务器会回答那个文件是空的。

    如果您想发送文件,您可以稍后添加内容(如我的示例中所示),但这是不好的方法。根据documentation,您应该使用另一种技术来发送文件数据。发送带有变量filename 的数组,文件路径以@ 为前缀或使用CURLFile(如here

    【讨论】:

    • 它作为表单数据发送,而不仅仅是一个纯文件。这就是邮递员以这种方式生成它的原因。问题是 $filename 在预先填充时以空白形式出现在 API 中
    • 详尽的解释。我不知道数据必须单独通知服务器
    猜你喜欢
    • 1970-01-01
    • 2013-03-24
    • 2015-04-02
    • 1970-01-01
    • 2015-12-18
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多