【问题标题】:PHP cURL Upload file without processingPHP cURL 上传文件不做处理
【发布时间】:2015-08-14 19:55:54
【问题描述】:

我正在尝试使用 PHP cURL 将文件上传到 Rest API (Tableau Server Rest API) 端点。

file upload procedure 存在三个步骤:

  1. 启动文件上传(请求上传令牌)
  2. 追加文件上传(上传文件数据)
  3. 发布资源(保存文件)

我遇到了服务器问题,在第二步给我一个 500 状态代码。联系支持后,我们发现问题很可能是 curl 请求似乎使用了-data 标志而不是--data-binary 标志,这意味着请求正文上发生了某种编码,应该不 正在发生。这会导致服务器响应 500 状态代码而不是实际的错误消息...

我想知道如何在 PHP 中使用 --data-binary 标志发出 cURL 请求。

我当前代码的相关部分:

// more settings
$curl_opts[CURLOPT_CUSTOMREQUEST] = $method;
$curl_opts[CURLOPT_RETURNTRANSFER] = true;
$curl_opts[CURLOPT_HTTPHEADER] = $headers;
$curl_opts[CURLOPT_POSTFIELDS] = $body;
//more settings

curl_setopt_array( $this->ch, $curl_opts );
$responseBody = curl_exec( $this->ch );

$method 是“PUT”,$headers 包含一个带有Content-Type: multipart/mixed; boundary=boundary-string 的数组,$body 的构造如下:

$boundary = md5(date('r', time()));

$body = "--$boundary\n";
$body .= "Content-Disposition: name='request_payload'\nContent-Type: text/xml\n\n";
$body .= "\n--$boundary\n";
$body .= "Content-Disposition: name='tableau_file'; filename='$fileName'\nContent-Type: application/octet-stream\n\n";
$body .=  file_get_contents( $path );
$body .= "\n--$boundary--";

$boundary 与内容类型标头中的边界字符串相同。 我知道这是一种有点/非常混乱的方式来构建我的身体,我打算在我可以实际上传我的文件后立即使用 Mustache:S

(我想提一下,这是我在这里的第一篇文章,请温柔...)

【问题讨论】:

  • 展示你如何构建$body
  • 感谢您的建议,已添加:)

标签: php rest curl file-upload tableau-api


【解决方案1】:

CURLOPT_POSTFIELDS 可以接受 key=value 字段对的数组。不要建立自己的 mime 身体。

这就是你应该拥有的,真的:

$data = array(
    'tableau_file' => '@/path/to/file';
                       ^---tell curl this field is a file
    etc..
);

curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);

【讨论】:

  • 感谢您的回答!这是否意味着 curl 也会自动在文件周围添加所有 multipart/mixed 数据?我应该把我的身体写到php://temp 然后上传吗?或者我可以以某种方式将所有这些都放入数组中吗?
  • 如果 curl 看到你正在上传文件,它会自动切换到 multipart/form-data。您可能可以将其覆盖为 multipart/mixed,尽管我不知道在这种情况下会如何进行。
  • 好的...然后我会尝试上传“纯”文件(我不给它很大的工作机会可悲:S)然后我可以尝试将整个内容写入文件并上传...感谢您的帮助!
【解决方案2】:

我最终尝试在 PHP 中使用 exec 函数实现“--data-binary”。在我开始之前,我必须清理一些我的请求体构建代码。此清理涉及从字符串构建 ($body .= "this" . $that . "\n";) 迁移到模板引擎 (Mustache)。不知何故,这个改变解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    相关资源
    最近更新 更多