curl傳送請求上傳檔案(multipart file upload)
阿新 • • 發佈:2018-11-08
折騰一下午的問題
第三方介面需要我們傳multipart 上傳檔案
curl一直各種試不成功,用Restlet Client工具總是能成功!
對比傳送的頭,發現工具在Content-Type: multipart/form-data;後面多了個這個boundary
然後去查了下,果真問題在這,哎,下面程式碼給自己做個筆記
$file = [ 'http://imgcdn.taobao.com/test/_2a501d5fd1bc84fa6b29d648fb3f37ea.jpeg', 'http://imgcdn.taobao.com/test/_e0274d5ba694062e8b2ba4619c5002a8.jpeg', ]; curl_put($file); function read_file($file) { $fh = fopen($file, 'r') or die($file.'開啟失敗'); $con = stream_get_contents($fh); fclose($fh); return $con; } function curl_put($data) { $token = 'yaiWD9f30UxsRJphtqTw3Nom5360R8u3slYN'; $header = [ "X-Channel-Authorization:".$token, ]; $ch = curl_init(); //初始化CURL控制代碼 curl_setopt($ch, CURLOPT_URL, 'https://api-demo.xxxx.com/?docType=IDENTITY_CARD&appId=55568547'); //設定請求的URL curl_setopt ($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); //設為TRUE把curl_exec()結果轉化為字串,而不是直接輸出 curl_setopt($ch, CURLOPT_CUSTOMREQUEST,"PUT"); //設定請求方式 curl_custom_postfields($ch , $data , $header); curl_setopt($ch, CURLOPT_TIMEOUT, 30);//設定超時時間 $result = curl_exec($ch); var_dump($result); echo $http_status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); } function curl_custom_postfields($ch, array $files = array() , array $header = array() ) { foreach ($files as $k => $v) { $data = read_file($v); $v = call_user_func("end", explode(DIRECTORY_SEPARATOR, $v)); $k = str_replace($disallow, "_", $k); $v = str_replace($disallow, "_", $v); $body[] = implode("\r\n", array( "Content-Disposition: form-data; name=\"docFiles\"; filename=\"{$v}\"", "Content-Type: application/octet-stream", "", $data, )); } // generate safe boundary do { $boundary = "---------------------" . md5(mt_rand() . microtime()); } while (preg_grep("/{$boundary}/", $body)); // add boundary for each parameters array_walk($body, function (&$part) use ($boundary) { $part = "--{$boundary}\r\n{$part}"; }); // add final boundary $body[] = "--{$boundary}--"; $body[] = ""; // set options return @curl_setopt_array($ch, array( CURLOPT_POST => true, CURLOPT_POSTFIELDS => implode("\r\n", $body), CURLOPT_HTTPHEADER => array_merge($header , array( "Expect: 100-continue", "Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type )), )); }