PHP中curl的CURLOPT_POSTFIELDS參數使用細節

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);

相關文章
相關標籤/搜索