2011-12-22 98 views
1

如何设置多个内容类型?我必须传递一个数组来请求body。该数组包含二进制文本和图像。如何设置多个内容类型?

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' 
)); 

的问题是主机不理解图像的格式,所以我需要传递更多的内容类型“图像/ 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

当问一个问题时,只用简单的语言描述你的目标,而不使用你不懂的术语,这总是一个好主意。 – 2011-12-22 04:16:37

+0

http://stackoverflow.com/questions/4074936/how-to-use-php-curl-to-send-images-with-the-correct-content-type – 2011-12-22 04:19:35

+1

@ Col.Shrapnel,我了解他。他意思是'multipart/form-data'主体文件“part”的Content-Type头。他恰当地使用这些条款。 – 2011-12-22 04:38:35

回答

1

首先尝试不对您的状态字段进行编码(即删除rawurlencode)。这是一个双重编码,可能这就是您的主持人抱怨的原因。

(顺便说一句,你不需要明确设置Content-Type头,卷曲将这样做。)

如果这还不够,你要么必须重新安排你的要求来使用卷曲的神奇的文件上传机制,或者你必须自己构造整个multipart/form-data字符串。

这是卷曲的魔力文件的机制是如何工作的(从文档到CURLOPT_POSTFIELDS

完整数据的HTTP“POST”操作后要发布一个文件,在前面加上@和使用的文件名文件类型可以通过跟随格式'; type = mimetype'类型的文件名显式指定,该参数可以作为urlencoded字符串传递,如'para1 = val1 & para2 = val2 & ... '或作为字段名称作为键和字段数据作为值的数组如果value是一个数组,则Content-Type头将设置为multipart/form-data。从PHP 5.2.0开始,value必须是数组如果文件传递给thi s选项和@前缀。

传递内容类型的特定字段的使用CURL多部分/格式数据POST的唯一方法是用如下语法字段值:@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发送的文件名 - 它将永远是正确的。

如果您不愿意创建临时文件并且必须使用CURL,则必须在内存中创建整个多部分/表单数据主体作为字符串,并将其作为字符串以CURL形式提供给CURL_POSTFIELDS,并手动将内容类型标题设置为multipart/form-data。这留给读者作为练习。此时,您应该考虑使用HTTP extension来代替,或者甚至使用fopenstream_context_create()来设置http方法和标头。

相关问题