【问题标题】:Curl PHP PUT request changes file contentCurl PHP PUT 请求更改文件内容
【发布时间】:2017-07-25 10:37:29
【问题描述】:

我在我的一个脚本中使用带有 curl php 的 PUT 请求,以使用 REST API 将文件上传到外部文件存储库。但是,上传的文件在文件的开头和结尾都包含有关 Content-Disposition、Content-Type 和一些字母数字代码的信息,除非再次手动结束,否则将变得无用。

不必要的开销如下所示:

--------------e876c4b8eee91562 内容处置:表单数据;名称=“测试文件”;文件名="test_3.xlsx" 内容类型: 应用程序/八位字节流

我用来做请求的代码是:

  $ch = curl_init($upload_url);
  $cfile = new CURLFile($file_realpath, 'application/octet-stream', $base_file_name);
  $data = array ('test_file' => $cfile);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
  curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Accept:application/json',
    'Content-Type:application/octet-stream',
  ));
  b2share_ignore_certificates($ch);
  curl_setopt($ch, CURLINFO_HEADER_OUT, true);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $output = curl_exec($ch);

  $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  $headerSent = curl_getinfo($ch, CURLINFO_HEADER_OUT);

  curl_close($ch);

我无法将请求更改为 POST,因为另一端的 REST API 需要 PUT 请求。关于如何摆脱开销的任何想法?

【问题讨论】:

  • 这只是标题。如果您查看完整的请求,即使 POST 请求也是如此。唯一的区别是 PHP 会解析 POST 变量并将它们放入一个不错的超级全局 ($_POST) 中,而您需要自己解析使用 PUT 方法发送的任何参数。任何需要 PUT 的 API 都应该能够处理它。
  • 您是否遇到了一些具体问题,或者您只是想“清理”数据以提高美观度?
  • 您的代码根本不应该工作。向 api 开发人员发送错误报告,表明此代码在它应该以 HTTP 400 Bad Request 响应拒绝上传时接受上传。您发送 application/json-content 类型的 multipart/form-data-encoded 请求,这根本不应该工作,它有两种完全不同的编码,并且它是 API 接受它的错误。至于修复你的代码,你需要下定决心,你是要上传一个 JSON 编码的请求,还是一个 multipart/form-data 请求?您当前的代码告诉服务器您正在提供json,但提供了multipart/form-data
  • @MagnusEriksson 是的,问题是实际文件包含该开销,例如Excel 无法再打开 xlsx
  • @stopopol 不,问题是您告诉服务器您的上传是 json 编码的,但实际上它是 multipart/form-data 编码的。如果服务器尝试将该请求解析为 json,则 Excel 将不会被上传而不会损坏。

标签: php curl libcurl


【解决方案1】:

好的。我在这里找到了问题的答案: PHP Curl post a file without header

因此换行

curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents($file_realpath));

解决了这个问题。这可能不是一个非常“干净”的解决方案,但它确实有效。不过,我很高兴听到更好的解决方案。

【讨论】:

  • 由于您要上传的文件可能很大,您可以考虑使用 CURLOPTS_INFILE 而不是 file_get_contents() 必须将整个文件内容加载到内存中
【解决方案2】:

只是作为一个说明(我还没有足够的积分来制作 cmets)。

我认为@stopopol 的答案实际上是正确的。我不是 PHP 专家,但在我看来,您确实在发送键/值表单数据。 B2SHARE API 需要二进制内容,并将您发送给它的内容准确地保存为文件。 标头没问题。 'Accept:application/json' 没有指定您发送的文件的内容类型,而是您期望返回的类型,即来自服务器的答案。

另请注意,B2SHARE 文档中给出的 curl 命令存在错误。很快就会修复。文件上传应使用--data-binary:

curl -X PUT -H 'Accept:application/json' -H 'Content-Type:application/octet-stream' --data-binary @TestFileToBeUploaded.txt https://$HOSTNAME/api/files/$FILE_BUCKET_ID/TestFileToBeUploaded.txt?access_token=$ACCESS_TOKEN

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多