2012年7月18日 星期三

用PHP+cURL傳送Request (GET,POST或上傳檔案)至另一個網頁

筆記分二大部份:PHP傳送GET、POST、上傳檔案至另一個網址,以及PHP如何接收及處理上傳的檔案。正常來講PHP程式通常是接收端,但有些時候也會扮演傳送端,把資料送到同一個或另一個伺服器,或者讀取某個網頁資料,這時可以用fopen、fsockopen或者cURL,後者功能強大且使用起來很便利、程式碼也很美觀直覺,相當推薦使用。


簡易的使用語法(GET):


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://SomeDomain/SamplePath?SomeVar=test");
curl_exec($ch);
curl_close($ch);

Get參數可以直接在網址傳遞,但是一旦資料量很大,用POST送還是比較適合


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://SomeDomain/SamplePath");
curl_setopt($ch, CURLOPT_POST, true); // 啟用POST
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query( array( "a"=>"123", "b"=>"321") )); 
curl_exec($ch); 
curl_close($ch);

CURLOPT_POSTFIELDS參數即為POST的內容,而 http_build_query() 效果是將array併成 a=123&b=321 型式的字串,POST內容會在header中標示以application/x-www-form-urlencoded型式傳送,如果不用字串而直接給array也可以,傳送方式則會變成multipart/form-data,但是封包會變大,且可能不被某些Server接受,通常是傳送檔案時才用。cURL有很多參數可以設置,詳細用法見PHP官網

進階的POST範例,參數設置還可以用array的方式取代:



$toURL = "http://SomeDomain/SamplePath?SomeVar=XX";
$post = array(
  "a"=>"123",
  "b"=>"321",
);
$ch = curl_init();
$options = array(
  CURLOPT_URL=>$toURL,
  CURLOPT_HEADER=>0,
  CURLOPT_VERBOSE=>0,
  CURLOPT_RETURNTRANSFER=>true,
  CURLOPT_USERAGENT=>"Mozilla/4.0 (compatible;)",
  CURLOPT_POST=>true,
  CURLOPT_POSTFIELDS=>http_build_query($post),
);
curl_setopt_array($ch, $options);
// CURLOPT_RETURNTRANSFER=true 會傳回網頁回應,
// false 時只回傳成功與否
$result = curl_exec($ch); 
curl_close($ch);
echo $result;


如果要挾帶檔案,和一般的POST動作一樣,只需注意二點:
  1. 以multipart/form-data模式傳送
  2. array內容前面加個@符號,後面接檔案的「絕對路徑」
cURL會自動去讀檔和計算大小,相當方便!

POST檔案範例:

$toURL = "http://SomeDomain/SamplePath?SomeVar=XX";
$post = array(
  "a"=>"123",
  "userfile"=>"@C:/XXX/OOO/oxox.doc",
  //檔案若和程式在同一目錄或相對目錄, 可以用getcwd(), 如:
  // "userfile"=>"@".getcwd()."/oxox.doc",
  // 另外還可以在檔名後面加上分號指定mimetype(較新版的PHP才能使用)
  // (預設的 mimetype 為application/octet-stream)
  // "userfile"=>"@".getcwd()."\\somePic.png;type=image/png"
);
$ch = curl_init();
$options = array(
  CURLOPT_URL=>$toURL,
  CURLOPT_POST=>true,
  CURLOPT_POSTFIELDS=>$post, // 直接給array
);
curl_setopt_array($ch, $options);
curl_exec($ch); 
curl_close($ch);


想挾帶多個檔案也可以,只要在array中增加即可。上段程式碼等同於在如下的HTML form中送出資料:


因為是HTML標準所以接收端不限於PHP,任何語言都可以,若接收端為PHP時,一樣是處理$_FILES變數,例如下面的程式碼:


if ($_FILES["userfile"]["error"] > 0)
{
  echo "Error: ".$_FILES["userfile"]["error"]."
";
}
else
{
  echo "檔名: ".$_FILES["userfile"]["name"]."
";
  echo "Type: ".$_FILES["userfile"]["type"]."
";
  echo "Size: ".($_FILES["userfile"]["size"]/1024)." Kb
";
  echo "暫存位置: ".$_FILES["userfile"]["tmp_name"];
轉貼來源:http://blog.roodo.com/esabear/archives/16358749.html

沒有留言: