首页 文章

使用 Curl 和 PHP 将多部分 PUT 上载到 REST 端点

提问于
浏览
2

我需要 HTTP 使用 PHP 和 Curl 的多部分 POST 将一个 csv 文件和一些 POST 字段发送到 REST API 端点。

文件上载的内容存储在变量$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 上提到的 PUT 格式

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 回答

  • 5

    仅供参考multipart/form-data。你需要自己构建一个身体,我认为我不认为 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);
    

    如果您对此有任何问题,请在 cURL 请求之前尝试echo $requestBody;,并确保它看起来像您期望的那样。

相关问题