如何使用PHP發送POST請求?


Answers

使用PHP5的CURL-less方法:

$url = 'http://server.com/path';
$data = array('key1' => 'value1', 'key2' => 'value2');

// use key 'http' even if you send the request to https://...
$options = array(
    'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data)
    )
);
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { /* Handle error */ }

var_dump($result);

有關該方法以及如何添加標頭的更多信息,請參閱PHP手冊,例如:

Question

其實我想讀取搜索查詢後的內容,當它完成時。 問題是該URL只接受POST方法,並且不會對GET方法執行任何操作...

我必須在domdocumentfile_get_contents()的幫助下閱讀所有內容。 有沒有什麼方法可以讓我用POST方法發送參數,然後通過PHP讀取內容?




試試PEAR的HTTP_Request2包來輕鬆發送POST請求。 或者,您可以使用PHP的curl函數或使用PHP 流上下文

HTTP_Request2還可以模擬出服務器,因此您可以輕鬆地對代碼進行單元測試




如果你這樣做,還有另一種CURL方法。

這一點非常簡單,只要您將頭部放在PHP curl擴展的工作方式中,將各種標誌與setopt()調用結合在一起。 在這個例子中,我有一個變量$ xml,它包含我準備發送的XML - 我將把它的內容髮佈到示例的測試方法。

$url = 'http://api.example.com/services/xmlrpc/';
$ch = curl_init($url);

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);
//process $response

首先我們初始化連接,然後使用setopt()設置一些選項。 這些告訴PHP我們正在發送一個post請求,並且我們正在發送一些數據,提供數據。 CURLOPT_RETURNTRANSFER標誌告訴curl給我們輸出curl_exec的返回值,而不是輸出它。 然後我們撥打電話並關閉連接 - 結果是$回應。




還有一個你可以使用的

<?php
$fields = array(
    'name' => 'mike',
    'pass' => 'se_ret'
);
$files = array(
    array(
        'name' => 'uimg',
        'type' => 'image/jpeg',
        'file' => './profile.jpg',
    )
);

$response = http_post_fields("http://www.example.com/", $fields, $files);
?>

點擊這裡查看詳情




上述無捲曲方法的另一種替代方法是使用本地功能:

這些POST函數可以簡單地如下所示:

<?php

function post_request($url, array $params) {
  $query_content = http_build_query($params);
  $fp = fopen($url, 'r', FALSE, // do not use_include_path
    stream_context_create([
    'http' => [
      'header'  => [ // header array does not need '\r\n'
        'Content-type: application/x-www-form-urlencoded',
        'Content-Length: ' . strlen($query_content)
      ],
      'method'  => 'POST',
      'content' => $query_content
    ]
  ]));
  if ($fp === FALSE) {
    fclose($fp);
    return json_encode(['error' => 'Failed to get contents...']);
  }
  $result = stream_get_contents($fp); // no maxlength/offset
  fclose($fp);
  return $result;
}



我使用以下函數使用curl發布數據。 $ data是要發布的字段數組(將使用http_build_query正確編碼)。 數據使用application / x-www-form-urlencoded進行編碼。

function httpPost($url, $data)
{
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($curl);
    curl_close($curl);
    return $response;
}

@Edward提到可以省略http_build_query,因為curl會正確編碼傳遞給CURLOPT_POSTFIELDS參數的數組,但是請注意,在這種情況下,數據將使用multipart / form-data編碼。

我將這個函數用於希望使用application / x-www-form-urlencoded編碼數據的API。 這就是為什麼我使用http_build_query()。




我確實嘗試過這個,它工作的很好......正如我所知道的那樣..

<?php
$url = $file_name;
$fields = array(
            '__VIEWSTATE'=>urlencode($state),
            '__EVENTVALIDATION'=>urlencode($valid),
            'btnSubmit'=>urlencode('Submit')
        );

//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
$fields_string = rtrim($fields_string,'&');

//open connection
$ch = curl_init();

//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);

//execute post
$result = curl_exec($ch);
print $result;
?>



更靈活的功能。 這可以使用或不使用CURL。

public function http_post($url){
        $postdata = array();

        if(strpos($url,"?") !== FALSE){
            $qsr = array();
            $url_r = explode("?", $url);
            $url = $url_r[0];
            parse_str($url_r[1], $qsr);
            $postdata = http_build_query($qsr);
        }

        $opts = array('http' =>
            array(
                'method'  => 'POST',
                'header'  => 'Content-type: application/x-www-form-urlencoded',
                'content' => $postdata
            )
        );

        $context  = stream_context_create($opts);
        $output = @file_get_contents($url, false, $context);

        if($output === FALSE) {
            if (function_exists('curl_init')){ 
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_POST, 1);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                $output = curl_exec($ch);
                curl_close ($ch);
            }
        }
        return $output;
    }

用法:

$output = http_post("https://www.example.com?secret=ALDJFNEK&response=123&remoteip=127.0.0.1");



我想補充一些關於Fred Tanrikut基於捲曲的答案的想法。 我知道他們中的大多數已經寫在上面的答案中,但我認為最好是展示一個包含所有這些答案的答案。

這裡是我寫的基於curl的HTTP-GET / POST / PUT / DELETE請求的類,涉及響應主體:

class HTTPRequester {
    /**
     * @description Make HTTP-GET call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPGet($url, array $params) {
        $query = http_build_query($params); 
        $ch    = curl_init($url.'?'.$query);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }
    /**
     * @description Make HTTP-POST call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPPost($url, array $params) {
        $query = http_build_query($params);
        $ch    = curl_init();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }
    /**
     * @description Make HTTP-PUT call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPPut($url, array $params) {
        $query = \http_build_query($params);
        $ch    = \curl_init();
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
        \curl_setopt($ch, \CURLOPT_HEADER, false);
        \curl_setopt($ch, \CURLOPT_URL, $url);
        \curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'PUT');
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
        $response = \curl_exec($ch);
        \curl_close($ch);
        return $response;
    }
    /**
     * @category Make HTTP-DELETE call
     * @param    $url
     * @param    array $params
     * @return   HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPDelete($url, array $params) {
        $query = \http_build_query($params);
        $ch    = \curl_init();
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
        \curl_setopt($ch, \CURLOPT_HEADER, false);
        \curl_setopt($ch, \CURLOPT_URL, $url);
        \curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'DELETE');
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
        $response = \curl_exec($ch);
        \curl_close($ch);
        return $response;
    }
}

改進

使用示例

得到

$response = HTTPRequester::HTTPGet("http://localhost/service/foobar.php", array("getParam" => "foobar"));

POST

$response = HTTPRequester::HTTPPost("http://localhost/service/foobar.php", array("postParam" => "foobar"));

$response = HTTPRequester::HTTPPut("http://localhost/service/foobar.php", array("putParam" => "foobar"));

刪除

$response = HTTPRequester::HTTPDelete("http://localhost/service/foobar.php", array("deleteParam" => "foobar"));

測試

你也可以通過使用這個簡單的類來做一些很酷的服務測試。

class HTTPRequesterCase extends TestCase {
    /**
     * @description test static method HTTPGet
     */
    public function testHTTPGet() {
        $requestArr = array("getLicenses" => 1);
        $url        = "http://localhost/project/req/licenseService.php";
        $this->assertEquals(HTTPRequester::HTTPGet($url, $requestArr), '[{"error":false,"val":["NONE","AGPL","GPLv3"]}]');
    }
    /**
     * @description test static method HTTPPost
     */
    public function testHTTPPost() {
        $requestArr = array("addPerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPPost($url, $requestArr), '[{"error":false}]');
    }
    /**
     * @description test static method HTTPPut
     */
    public function testHTTPPut() {
        $requestArr = array("updatePerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPPut($url, $requestArr), '[{"error":false}]');
    }
    /**
     * @description test static method HTTPDelete
     */
    public function testHTTPDelete() {
        $requestArr = array("deletePerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPDelete($url, $requestArr), '[{"error":false}]');
    }
}



我正在尋找類似的問題,並找到了一個更好的方法來做到這一點。 所以在這裡。

你可以簡單地把下面一行放在重定向頁面上(比如page1.php)。

header("Location: URL", TRUE, 307); // Replace URL with to be redirected URL, e.g. final.php

我需要這個重定向POST請求REST API調用。 此解決方案可以重定向發布數據以及自定義標題值。

這裡是參考鏈接




我建議您使用經過完全單元測試並使用最新編碼實踐的開放源代碼包guzzle

安裝Guzzle

轉到項目文件夾中的命令行並鍵入以下命令(假設您已經安裝了包管理器composer )。 如果你需要幫助如何安裝Composer, 你應該看看這裡

php composer.phar require guzzlehttp/guzzle

使用Guzzle發送POST請求

Guzzle的使用非常簡單,因為它使用了一個輕量級的面向對象的API:

// Initialize Guzzle client
$client = new GuzzleHttp\Client();

// Create a POST request
$response = $client->request(
    'POST',
    'http://example.org/',
    [
        'form_params' => [
            'key1' => 'value1',
            'key2' => 'value2'
        ]
    ]
);

// Parse the response object, e.g. read the headers, body, etc.
$headers = $response->getHeaders();
$body = $response->getBody();

// Output headers and body for debugging purposes
var_dump($headers, $body);



如果您有機會使用Wordpress開發您的應用程序(即使是非常簡單的東西,它實際上也是獲得授權,信息頁等的便捷方式),您可以使用以下代碼片段:

$response = wp_remote_post( $url, array('body' => $parameters));

if ( is_wp_error( $response ) ) {
    // $response->get_error_message()
} else {
    // $response['body']
}

它使用不同的方式來製作實際的HTTP請求,具體取決於Web服務器上可用的內容。 有關更多詳細信息,請參閱HTTP API文檔

如果您不想開發自定義主題或插件來啟動Wordpress引擎,則可以在wordpress根目錄中的隔離PHP文件中執行以下操作:

require_once( dirname(__FILE__) . '/wp-load.php' );

// ... your code

它不會顯示任何主題或輸出任何HTML,只需使用Wordpress API即可!