由於專案需要,需要本地伺服器接收資料後,再將資料轉送到另外一台伺服器上,故要用到模擬post請求傳送數據,當然資料中也包含檔案流。
curl是php比較常用的方式之一,一般程式碼如下:
- $params1 = "test";
- $params2 = "@".$ absolute_path;//如果是檔案則參數為"@" 絕對路徑
- $post_data = array(
- 'params1' => $params1,
- 'params2' => $params2,
- );
- function postData($url, $data){
- $ch = curl_init();
- $timeout = 300;
- curl_setopt($ch, CURLOPT_URL, $url); //請求位址
- //curl_setopt($ch, CURLOPT_REFERER, $ip);//建構來路
- curl_setopt($ch, CURLOPT_POST, true); //post請求
- curl_setopt($ch, CURLOPT_BIch, CURLOPT_NARY //二進位流
- curl_setopt($ch, CURLOPT_POSTFIELDS, $data); //資料
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //當CURLOPT_RETURNTRANERER被設定為1時返回🎜> curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); //設定請求逾時時間
- $handles = curl_exec($ch);
- curl_close($ch);
- return $hturn>; }
-
-
複製程式碼
對方是java伺服器,我只知道接口,並不知道對方如何處理文件接收的。上面這種方式在win7 wamp環境下是成功的,但是將程式碼放到centOS Nginx伺服器上卻失敗,回傳的訊息是檔案接收失敗。經過抓包分析,發現在win7 wamp下發的包和centos nginx下發的http包格式有差別。一般情況下curl預設把content_type設為了multipart/form-data,在我的機器上 win7 wamp下是如此,但是centos nginx下卻是application/x-www-form-urlencoded。當然這也可能是伺服器設定問題,只是我並不知道問題在哪裡。然後我 又查看了下PHP版本,同是PHP5.3.X,但有細微差別。也不排除是PHP版的問題。之後加入程式碼:
$header = array( 'Content-Type: multipart/form-data', - );
- curl_setopt( $ch, CURLOPT_HTTPHEAEA , $header);
-
-
複製程式碼
設定header,但在centos下依舊無效。居然無法改變content-type,簡直坑爹。
後來在技術總監的幫助下,看了PHP官方網站上的一個連結http://php.net/manual/en /class.curlfile.php,參照官網做法在win wamp和centos nginx下post請求都成功了。仔細閱讀了程式碼,發現做法竟是完整的書寫了http請求的body部分,而不用curl自己生成的部分,不得不佩服。 下面放出程式碼:
- function postData($url, $data = array(), $data1 = array()){
- $header = array(
- 'Content-Type: multipart/form-data',
- );
- $ch = curl_init();
- curl_setopt ($ch, CURLOPT_URL, $url);
- curl_setopt( $ch, CURLOPT_HTTPHEADER, $header);
- curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT,10) curl_custom_postfields($ch, $data, $data1);
- $dxycontent = curl_exec($ch);
- curl_close($ch) }
-
- /**
- * 用於 PHP5.3 ~ PHP 5.4 的安全多部分 POST 請求。
- *
- * @param resource $ch cURL 資源
- * @param array $assoc "name => value"
- * @param array $files "name => path"
- * @ @ return 布爾
- */
- function curl_custom_postfields($ch, array $assoc = array(), array $files = array($ch, array $assoc = array(), array $files = array()) {
- // invalid characters for "name" and "filename"
- static $disallow = array("
- 參數傳遞無影響,若是檔案則在絕對路徑前 "@"。唯一的區別就是將檔案資料和普通資料用不同的陣列區分開來,在模擬http的body部分時對其進行不同的處理。最終成功上傳文件。
-
-
-
-
php, post
-
-
-
-
-
-
-
|