web-dev-qa-db-ja.com

PHP "php:// input" vs $ _POST

JQueryからのAjaxリクエストと対話するときは、php://inputではなくメソッド$_POSTを使用するように指示されています。私が理解できないのは、これを使用する利点と$_POSTまたは$_GETのグローバルメソッドを比較することです。

205
Lee

その理由は、php://inputは、コンテンツタイプに関係なく、リクエストのHTTPヘッダーの後にすべての生データを返すためです。

PHPスーパーグローバル$_POSTのみがデータをラップすることになっています

  • application/x-www-form-urlencoded(単純なフォーム投稿の標準コンテンツタイプ)または
  • multipart/form-data-encoded(主にファイルのアップロードに使用)

これは、これらが唯一のコンテンツタイプであるためです mustはユーザーエージェントによってサポートされる 。そのため、サーバーとPHPは従来、他のコンテンツタイプを受信することを期待していません(受信できなかったという意味ではありません)。

したがって、単にPOST古き良きHTML formである場合、リクエストは次のようになります。

POST /page.php HTTP/1.1

key1=value1&key2=value2&key3=value3

ただし、Ajaxを頻繁に使用している場合、この問題には、より複雑なデータを型(文字列、int、bool)および構造体(配列、オブジェクト)と交換することも含まれるため、ほとんどの場合、JSONが最適です。ただし、JSONペイロードを含むリクエストは次のようになります。

POST /page.php HTTP/1.1

{"key1":"value1","key2":"value2","key3":"value3"}

コンテンツはapplication/json(または少なくとも上記のいずれでもない)になるため、PHPの$_POST- wrapperはその処理方法を(まだ)知りません。

データはまだそこにあり、ラッパーを介してアクセスすることはできません。したがって、file_get_contents('php://input')で生の形式で自分で取得する必要があります( multipart/form-data- encodedでない限り )。

これは、XMLデータまたはその他の非標準コンテンツタイプにアクセスする方法でもあります。

412
Quasdunk

php://inputはあなたにデータの生のバイトを与えることができます。 POSTされたデータがJSONエンコードされた構造である場合、これは役に立ちます。これは、AJAX POST要求の場合によくあります。

これを行うための関数があります。

  /**
   * Returns the JSON encoded POST data, if any, as an object.
   * 
   * @return Object|null
   */
  private function retrieveJsonPostData()
  {
    // get the raw POST data
    $rawData = file_get_contents("php://input");

    // this returns null if not valid json
    return json_decode($rawData);
  }

$_POST配列は、従来のPOSTによって送信されたフォームからのKey-Valueデータを処理しているときにもっと便利です。これはPOSTされたデータが認識されたフォーマット、通常はapplication/x-www-form-urlencodedである場合にのみ機能します( http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4を参照 詳細)。

45
Rob Agar

投稿データが不正な形式の場合、$ _POSTには何も含まれません。それでも、php:// inputには不正な形式の文字列が含まれます。

たとえば、ファイルをアップロードするための正しい投稿Key-Valueシーケンスを形成せず、すべてのファイルを投稿データとして、変数名などなしでダンプするだけのajaxアプリケーションがあります。 $ _POSTは空になり、$ _FILESも空になり、php://入力は文字列として書かれた正確なファイルを含みます。

24
Nameless