CURL確實是一個不錯的好工具,不只在PHP中仍是其餘的操做系統中,都是一個很是好用的。可是若是你有些參數沒有用好的話,那可能會得不到本身理想中的結果。php
在一般狀況下,咱們使用 CURL 來提交 POST 數據的時候,咱們已經習慣了這樣的寫法:數組
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);瀏覽器
可是這樣的寫法在有時候並不會很好用,可能會獲得服務器返回的 500 錯誤。可是咱們嘗試在使用 Socket 方式向服務器提交數據的時候,咱們會獲得很是正確的結果。例如咱們在服務器上面存在一個以下的 PHP 文件:服務器
<?php print_r($_SERVER); ?>app
當咱們採用 CURL 在不注意細節的前提下向服務器發送一些數據,咱們可能獲得下面這樣的結果,這不是咱們理想中的結果:curl
[CONTENT_TYPE] => multipart/form-data; boundary=—————————-f924413ea122工具
可是若是咱們在採用 http_build_query($post_data) 來替代 $post_data 再向這個 PHP 腳本提交數據的時候,咱們就會獲得和上面不一樣的結果,這纔是咱們理想中的結果:post
[CONTENT_TYPE] => application/x-www-form-urlencodedui
從上面這個例子中不難看出,使用 CURL 而且參數爲數據時,向服務器提交數據的時候,HTTP頭會發送Content_type: application/x-www-form-urlencoded。這個是正常的網頁<form>提交表單時,瀏覽器發送的頭部。而 multipart/form-data 咱們知道這是用於上傳文件的表單。包括了 boundary 分界符,會多出不少字節。官方的手冊上是這樣說的:url
The full data to post in a HTTP 「POST」 operation. To post a file, prepend a filename with @ and use the full path. This can either be passed as a urlencoded string like ‘para1=val1¶2=val2&…' or as an array with the field name as key and field data as value. If value is an array, the Content-Type header will be set to multipart/form-data.
使用數組提供 post 數據時,CURL 組件大概是爲了兼容 @filename 這種上傳文件的寫法,默認把 content_type 設爲了 multipart/form-data。雖然對於大多數服務器並無影響,可是仍是有少部分服務器不兼容。
通過一番總結最終得出結論:
在沒有須要上傳文件的狀況下,儘可能對 post 提交的數據進行 http_build_query 處理,而後再發送出去,能實現更好的兼容性,更小的請求數據包。
參考代碼:
01
<?php
02
/**
03
* PHP發送Post數據
04
*
05
* @param string $url 請求url
06
* @param array/string $params 發送的參數
07
* @return array
08
*/
09
function http_post_data($url, $params = array())
10
{
11
if (is_array($params))
12
{
13
$params = http_build_query($params, null, '&');
14
}
15
16
$ch = curl_init();
17
curl_setopt($ch, CURLOPT_POST, 1);
18
curl_setopt($ch, CURLOPT_URL, $url);
19
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
20
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
21
$response = curl_exec($ch);
22
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
23
curl_close($ch);
24
25
return array($httpCode, $response);
26
}
27
28
$url = "http://blog.snsgou.com";
29
$data = array('a' => 1, 'b' => 2, 'c' => 2);
30
list($returnCode, $returnContent) = http_post_data($url, $data);