2012-05-07 51 views
2

我需要HTTP使用帶PHP和Curl的多部分POST將一個csv文件和某些POST字段添加到REST API端點。使用Curl和PHP將多部分PUT上傳到REST端點

文件上傳的內容存儲在變量$ list中。另一個端點是$ url。

$ch = curl_init($url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_PUT, true); 
$post = array(
    //Other Post fields array 
); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $post); 

$fh = fopen('php://memory', 'rw'); 
fwrite($fh, $list); 
rewind($fh); 
curl_setopt($ch, CURLOPT_INFILE, $fh); 
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($list)); 
$response = curl_exec($ch); 

上面的代碼似乎工作的唯一問題是,另一端點需要對文件上傳指定字段名。我如何設置文件名?

我做錯了什麼?

這是他們的API

Content-Disposition: form-data; name="list[csv]"; filename="RackMultipart20110923-63966-hfpyg" 
Content-Length: 33 
Content-Type: text/csv 
Content-Transfer-Encoding: binary 

xxxx 
yyyy 
zzzz 
-------------MultipartPost 
Content-Disposition: form-data; name="list[list_type]" 

Blacklist 
-------------MultipartPost-- 
+1

您知道PUT是多部分數據的錯誤方法嗎? PUT請求應該與服務器上的文件內容直接相關,並且對於PUT多部分請求沒有多大意義 - 您確定不應該在發佈它嗎?看起來像POSTing ['multipart/form-data'](http://en.wikipedia.org/wiki/MIME#Form_Data)會在這裏變得更有意義...該文件將被指定爲具有「Content-Disposition : 附件; NAME = 「字段名」; filename =「文件名」標題 – DaveRandom

+0

1. REST端點需要一個PUT。 2.使用POST進行文件上傳需要我在POST數組中指定一個文件名,我需要從一個變量上傳它。可能一箇中間解決方案可能是從變量創建一個臨時文件並上傳它,但我不想這樣做。 –

+0

什麼是您發送的內容的MIME類型?您能否向我們展示端點的任何API文檔?我不明白如何在不使用某種形式的'multipart/*'類型的情況下指定一個文件名稱,在這種情況下,它是您需要的'Content-Disposition'頭部 - 但您可能需要自己構造消息主體。 – DaveRandom

回答

5

FYI是multipart/form-data提到的PUT格式。您將需要自己構建主體,我認爲我不認爲cURL可以通過PUT請求來構建這種請求。然而,這並不是一個嚴重的問題:

<?php 

    function recursive_array_mpfd ($array, $separator, &$output, $prefix = '') { 
    // Recurses through a multidimensional array and populates $output with a 
    // multipart/form-data string representing the data 
    foreach ($array as $key => $val) { 
     $name = ($prefix) ? $prefix."[".$key."]" : $key; 
     if (is_array($val)) { 
     recursive_array_mpfd($val, $separator, $output, $name); 
     } else { 
     $output .= "--$separator\r\n" 
       . "Content-Disposition: form-data; name=\"$name\"\r\n" 
       . "\r\n" 
       . "$val\r\n"; 
     } 
    } 
    } 

    // This will hold the request body string 
    $requestBody = ''; 

    // We'll need a separator 
    $separator = '-----'.md5(microtime()).'-----'; 

    // First add the postfields 
    $post = array(
    //Other Post fields array 
); 
    recursive_array_mpfd($post, $separator, $requestBody); 

    // Now add the file 
    $list = "this,is,some,csv,data"; // The content of the file 
    $filename = "data.csv"; // The name of the file 
    $requestBody .= "--$separator\r\n" 
       . "Content-Disposition: form-data; name=\"list[list_type]\"; filename=\"$filename\"\r\n" 
       . "Content-Length: ".strlen($list)."\r\n" 
       . "Content-Type: text/csv\r\n" 
       . "Content-Transfer-Encoding: binary\r\n" 
       . "\r\n" 
       . "$list\r\n"; 

    // Terminate the body 
    $requestBody .= "--$separator--"; 

    // Let's go cURLing... 
    $ch = curl_init($url); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($ch, CURLOPT_PUT, true); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: multipart/form-data; boundary="'.$separator.'"' 
)); 
    $response = curl_exec($ch); 

如果您有任何這方面的問題,請嘗試echo $requestBody;捲曲請求之前,並確保它看起來像你期望它。

+0

+很好的答案..... – Baba

相關問題