2011年8月18日 21:08

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

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

  在正常預設安裝之下,PHP安裝目錄下會有 libeay32.dll 和 ssleay32.dll 二個檔案,且在phpinfo()中會看到curl已啟用,即可使用之。以下做一點心得紀錄。

簡易的使用語法(GET):

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

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

簡單的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中送出資料:

<form action="http://SomeDomain/SamplePath?SomeVar=XX" method="post" enctype="multipart/form-data">
<input type="file" name="userfile" id="userfile" />
<input type="hidden" name="a" value="123" />
<input type="submit" name="submit" value="Submit" />
</form>

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

if ($_FILES["userfile"]["error"] > 0)
{
	echo "Error: ".$_FILES["userfile"]["error"]."<br />";
}
else
{
	echo "檔名: ".$_FILES["userfile"]["name"]."<br />";
	echo "Type: ".$_FILES["userfile"]["type"]."<br />";
	echo "Size: ".($_FILES["userfile"]["size"]/1024)." Kb<br/>";
	echo "暫存位置: ".$_FILES["userfile"]["tmp_name"];
}
延伸閱讀:

  • esabear 發表於樂多回應(0)引用(0)網頁製作編輯本文
    樂多分類:網路/3C切換閱讀版型 │昨日人次:66 │累計人次:36078 │標籤:心得,技術,PHP
     

    引用URL

    http://cgi.blog.roodo.com/trackback/16358749

     
     


     
    x