PHP cURL 不处理上传文件
PHP cURL Upload file without processing
我正在尝试使用 PHP cURL 将文件上传到 Rest API (Tableau Server Rest API) 端点。
file upload procedure存在三个步骤:
- 启动文件上传(请求上传令牌)
- Append file upload(上传文件数据)
- 发布资源(保存文件)
我遇到了服务器问题,在第二步给我一个 500 状态代码。联系支持人员后,我们发现问题很可能是 curl 请求似乎使用 -data
标志而不是 --data-binary
标志,这意味着请求 [=57= 发生了某种编码] 这应该 不会 发生。这会导致服务器响应 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
与 content-type header 中的 boundary-string 相同。
我知道这是构建我的 body 的 kinda/very 混乱方式,我计划在我真正上传文件后尽快使用 Mustache :S
(我想说这是我第一次post来这里,请温柔...)
CURLOPT_POSTFIELDS 可以接受键=值字段对的数组。不要建立你自己的 mime body.
这就是你应该拥有的,真的:
$data = array(
'tableau_file' => '@/path/to/file';
^---tell curl this field is a file
etc..
);
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
我最终尝试使用 PHP 中的 exec
函数实现“--data-binary”。在我开始之前,我必须清理一些我请求的健身代码。此清理涉及从字符串构建 ($body .= "this" . $that . "\n";
) 转移到模板引擎 (Mustache)。此更改以某种方式解决了问题。
我正在尝试使用 PHP cURL 将文件上传到 Rest API (Tableau Server Rest API) 端点。
file upload procedure存在三个步骤:
- 启动文件上传(请求上传令牌)
- Append file upload(上传文件数据)
- 发布资源(保存文件)
我遇到了服务器问题,在第二步给我一个 500 状态代码。联系支持人员后,我们发现问题很可能是 curl 请求似乎使用 -data
标志而不是 --data-binary
标志,这意味着请求 [=57= 发生了某种编码] 这应该 不会 发生。这会导致服务器响应 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
与 content-type header 中的 boundary-string 相同。
我知道这是构建我的 body 的 kinda/very 混乱方式,我计划在我真正上传文件后尽快使用 Mustache :S
(我想说这是我第一次post来这里,请温柔...)
CURLOPT_POSTFIELDS 可以接受键=值字段对的数组。不要建立你自己的 mime body.
这就是你应该拥有的,真的:
$data = array(
'tableau_file' => '@/path/to/file';
^---tell curl this field is a file
etc..
);
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
我最终尝试使用 PHP 中的 exec
函数实现“--data-binary”。在我开始之前,我必须清理一些我请求的健身代码。此清理涉及从字符串构建 ($body .= "this" . $that . "\n";
) 转移到模板引擎 (Mustache)。此更改以某种方式解决了问题。