web-dev-qa-db-ja.com

どうやって送るの? POST PHPでリクエスト?

実際には、検索クエリの後に来る内容を読み終えたら読みたいと思います。問題は、URLがPOSTメソッドのみを受け入れ、GETメソッドでは何もしないことです。

私はdomdocumentfile_get_contents()の助けを借りてすべての内容を読まなければなりません。 POSTメソッドを使用してパラメータを送信してからPHPを介してコンテンツを読み取ることを可能にする方法はありますか。

586
Fred Tanrikut

PHP 5でのCURLなしの方法

$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のマニュアルを見てください。例えば:

1128
dbau

あなたはcURLを使用することができます:

<?php
//The url you wish to send the POST request to
$url = $file_name;

//The data you want to send via POST
$fields = [
    '__VIEWSTATE '      => $state,
    '__EVENTVALIDATION' => $valid,
    'btnSubmit'         => 'Submit'
];

//url-ify the data for the POST
$fields_string = http_build_query($fields);

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

//So that curl_exec returns the contents of the cURL; rather than echoing it
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true); 

//execute post
$result = curl_exec($ch);
echo $result;
?>
86
Fred Tanrikut

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は、curlがCURLOPT_POSTFIELDSパラメータに渡された配列を正しくエンコードするのでhttp_build_queryを省略することができると述べていますが、この場合データはmultipart/form-dataを使ってエンコードされることをお勧めします。

この関数は、application/x-www-form-urlencodedを使用してデータがエンコードされることを期待するAPIと共に使用します。だからこそ私はhttp_build_query()を使用しています。

53
Dima L.

私はあなたがオープンソースパッケージ 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);
36
Andreas

そのようにしている場合は、別の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に、私たちが投稿要求をしていること、そしてそれを使ってデータを送っていることを伝えます。 CURLOPT_RETURNTRANSFERフラグは、出力を出力するのではなく、curl_execの戻り値として出力するようにcurlに指示します。それから呼び出しを行い、接続を閉じます - 結果は$ responseにあります。

23
Josip Ivic

万が一Wordpressを使ってあなたのアプリを開発しているのであれば(非常に単純なものであっても承認、情報ページなどを取得するのに実際には便利な方法です)、次のコードを使用できます。

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

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

Webサーバーで利用可能なものに応じて、実際のHTTPリクエストを作成する方法は異なります。詳細については、 HTTP APIドキュメント を参照してください。

Wordpressエンジンを起動するためのカスタムテーマやプラグインを開発したくない場合は、WordPressルートにある独立したPHPファイルで次のようにします。

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

// ... your code

テーマを表示したり、HTMLを出力したりすることはありません。WordpressAPIを使ってハックするだけです。

18
user3638471

カールベースのFred Tanrikutの答えについていくつか考えてみたい。私はそれらのほとんどがすでに上記の答えで書かれていることを知っています、しかし私はそれをすべて一緒に含む答えを示すことは良い考えだと思います。 

これは私がHTTP-GET/POST/PUT/DELETEリクエストをcurlに基づいて作成するために書いたクラスです。

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

改良点

  • Http_build_queryを使用してrequest-arrayからquery-stringを取得します(配列自体を使用することもできます。したがって、 http://php.net/manual/en/function.curl-setopt.php を参照してください)。 )
  • それをエコーする代わりに応答を返す。ただし、 curl_setopt($ ch、CURLOPT_RETURNTRANSFER、true);という行を削除することで戻るのを避けることができます。 。その後、戻り値はブール値(true =要求は成功し、そうでなければエラーが発生した)になり、応答がエコーされます。 参照: http://php.net/en/manual/function.curl-exec.php
  • curl_close を使用して、セッションの終了とcurl-handlerの削除をクリーンにします。参照してください: http://php.net/manual/en/function.curl-close.php
  • curl_setopt 関数に数値ではなくブール値を使用する(ゼロ以外の数値もtrueと見なされますが、trueを使用すると読みやすいコードが生成されますが、これは私の意見です) )
  • HTTP-PUT/DELETE呼び出しを実行する機能(RESTfulサービステストに役立ちます)

使用例

GET

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

DELETE

$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}]');
    }
}
16
mwatzer

上記の curl-lessメソッド の別の方法は、ネイティブstream 関数:

  • stream_context_create()

    optionsプリセットで指定されたオプションを使用して、ストリームコンテキストを作成して返します。

  • stream_get_contents()

    file_get_contents() と同じですが、stream_get_contents()が既に開いているストリームリソースを操作し、残りのコンテンツを最大でmaxlengthバイトで、指定されたoffsetから始まります。

これらの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;
}
13
CPHPython

あなたが使うことができるもう一つがあります

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

詳細はここをクリック

5
Code

私は同様の問題を探していて、これを行うためのより良いアプローチを見つけました。だからここに行きます。

次の行をリダイレクトページに置くだけです(たとえばpage1.php)。

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

_ rest _ API呼び出しに対するPOST要求をリダイレクトするためにこれが必要です。このソリューションは、投稿データとカスタムヘッダー値でリダイレクトできます。

これは 参照リンク です。

5
Arindam Nayak

簡単にPOSTリクエストを送るためにPEARの HTTP_Request2 パッケージを試してください。あるいは、PHPのcurl関数を使うか、PHP ストリームコンテキスト を使うことができます。

HTTP_Request2はサーバーをモックアウトすることも可能にするので、あなたはあなたのコードを簡単にユニットテストすることができます

1
cweiske

GETまたはPOSTリクエストをPHPとともに送信するためのより良い方法は以下のとおりです。

<?php
    $r = new HttpRequest('http://example.com/form.php', HttpRequest::METH_POST);
    $r->setOptions(array('cookies' => array('lang' => 'de')));
    $r->addPostFields(array('user' => 'mike', 'pass' => 's3c|r3t'));

    try {
        echo $r->send()->getBody();
    } catch (HttpException $ex) {
        echo $ex;
    }
?>

コードはこちらの公式ドキュメントから引用しています http://php.net/manual/it/httprequest.send.php

0
Imran Zahoor