如何设置多个内容类型?我必须传递一个数组来请求正文。该数组包含文本和二进制图像。
curl_setopt($apiCon, CURLOPT_POSTFIELDS, array(
'status' => rawurlencode($status),
'photo' => $photoInBinary
));
curl_setopt($apiCon, CURLOPT_HTTPHEADER, array(
'Host: api.mixi-platform.com',
'Authorization: OAuth ' . $accessToken,
'Content-Type: multipart/form-data'
));
问题是主机不了解图像的格式,所以我需要传递更多内容类型'image / jpg',但我不知道放在哪里。
以上代码有效,但只发布状态。
更新 好的,我的目标是将带有照片的状态发布到社交网络页面。
有关更多信息,请阅读: http://developer.mixi.co.jp/en/connect/mixi_graph_api/mixi_io_spec_top/voice-api/#toc-10
这是我的代码。它有效,但只发布状态,而不是照片。
$apiCon = curl_init(self::API_POST_STATUS_WITH_PHOTO);
curl_setopt($apiCon, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($apiCon, CURLOPT_RETURNTRANSFER, true);
curl_setopt($apiCon, CURLOPT_POST, true);
curl_setopt($apiCon, CURLOPT_POSTFIELDS, array('status' => rawurlencode($status), 'photo' => $photoInBinary));
curl_setopt($apiCon, CURLOPT_HTTPHEADER, array('Host: api.mixi-platform.com', 'Authorization: OAuth ' . $accessToken, 'Content-Type: multipart/form-data'));
$result = curl_exec($apiCon);
curl_close($apiCon);
答案 0 :(得分:1)
首先尝试不编码您的状态字段(即删除rawurlencode
)。这是一个双重编码,可能这就是你的主人抱怨的原因。
(另外,您不需要显式设置内容类型标头; CURL会这样做。)
如果这还不够,您必须重新安排使用CURL魔术文件上传机制的请求,或者您必须自己构建整个multipart / form-data字符串。
这就是CURL魔术文件机制的工作原理(从文档到CURLOPT_POSTFIELDS
:
要在HTTP“POST”操作中发布的完整数据。要发布文件,请在文件前加上@并使用完整路径。可以通过使用格式为'; type = mimetype'的类型的文件名来明确指定文件类型。此参数可以作为urlencoded字符串传递,如'para1 = val1& para2 = val2& ...',或者作为一个数组,字段名称为键,字段数据为值。如果value是数组,则Content-Type标头将设置为multipart / form-data。从PHP 5.2.0开始,如果使用@前缀将文件传递给此选项,则value必须是数组。
使用CURL在multipart / form-data POST中传递特定字段的content-type的唯一方法是使用以下字段值的语法:@filepath;type=mime/type
。
如果$photoInBinary
在文件中开始生效,只需将上述格式的文件名传递给CURL,而不是打开文件并读取数据。
但是,如果您自己在内存中创建了照片,则需要将其写入临时文件。以下是如何做到这一点:
function curlFileUploadData($data, $type='') {
// $data can be a string or a stream
$filename = tempnam(sys_get_temp_dir(), 'curlupload-');
file_put_contents($filename, $data);
$curlparam = "@{$filename}";
if ($type) {
$curlparam .= ";type={$type}";
}
return array($curlparam, $filename);
}
list($curlparam, $tmpfile) = curlFileUploadData('thedata', 'image/bmp');
// You can see the raw bits CURL sends if you run 'nc -l 9999' at a command line first
$c = curl_init('http://localhost:9999');
curl_setopt($c, CURLOPT_POSTFIELDS, array('status' => 'good', 'photo' => $curlparam));
curl_exec($c);
curl_close($c);
unlink($tmpfile); // REMEMBER TO DO THIS!!!!
请注意,CURL将在多部分文件上载中设置filename参数。确保主机不会将此用于任何重要的事情。据我所知,没有办法覆盖CURL发送的文件名 - 它将永远是给定的。
如果您不想创建临时文件并且必须使用CURL,则必须在内存中将整个multipart / form-data主体创建为字符串,并将其作为字符串提供给{{1并手动将内容类型标头设置为CURL_POSTFIELDS
。这留给读者练习。到目前为止,您应该考虑使用HTTP extension,甚至multipart/form-data
和fopen
来设置http方法和标题。