web-dev-qa-db-ja.com

phpでPOSTの本文を取得する方法

私はPOSTとしてphpページに以下を提出します:

{a:1}

これがリクエストの本文です(POSTリクエスト)。
phpでは、その値を抽出するために何をしなければなりませんか?

var_dump($_POST); 

解決策ではなく、機能していません。

219

POSTまたはPUT要求(または他のHTTPメソッド)のエンティティ本体にアクセスするには、次の手順を実行します。

$entityBody = file_get_contents('php://input');

また、STDIN定数はphp://inputへの既に開かれているストリームです。

$entityBody = stream_get_contents(STDIN);

I/Oストリームに関する PHPマニュアルエントリよりドキュメント

php:// inputはリクエストボディから生データを読み込むことができる読み込み専用のストリームです。 POSTリクエストの場合、特別なphp.iniディレクティブに依存しないので、$HTTP_RAW_POST_DATAの代わりにphp:// inputを使用するのが好ましいです。さらに、$HTTP_RAW_POST_DATAがデフォルトで設定されていない場合は、always_populate_raw_post_dataをアクティブにすることに代わる可能性があるメモリ集約的な代替手段です。 php:// inputはenctype = "multipart/form-data"では使用できません。

具体的には、Web SAPIでのアクセス方法に関係なく、php://inputストリームは検索不可能であることに注意してください。これは一度しか読めないことを意味します。大規模なHTTPエンティティ本体が定期的にアップロードされる環境で作業している場合は、(上記の最初の例のように入力をバッファリングするのではなく)ストリーム形式で入力を維持することをお勧めします。

このようなストリームリソースを維持することは役に立ちます。

<?php

function detectRequestBody() {
    $rawInput = fopen('php://input', 'r');
    $tempStream = fopen('php://temp', 'r+');
    stream_copy_to_stream($rawInput, $tempStream);
    rewind($tempStream);

    return $tempStream;
}

php://tempを使用すると、一定量のデータが格納された後(デフォルトでは2M)、透過的にファイルシステムストレージに切り替わるため、メモリ消費を管理できます。このサイズはphp.iniファイルまたは/maxmemory:NNを追加することで操作できます。ここでNNは一時ファイルを使用する前にメモリに保持するデータの最大量(バイト単位)です。

もちろん、入力ストリームを探す理由が特にない限り、Webアプリケーションにこの機能は必要ありません。 HTTPリクエストエンティティの本文を一度読むだけで十分です - アプリケーションが何をすべきかを判断している間、クライアントを一日中待たせないでください。

Php://入力は、Content-Type: multipart/form-dataヘッダー(HTMLフォームのenctype="multipart/form-data")を指定する要求には使用できません。これは、PHPがフォームデータをすでに$_POSTスーパーグローバルに解析したためです。

469
rdlowrey

空の$_POSTの考えられる理由は、要求がPOSTではなくなったか、もうPOSTではなくなったことです... postとして開始された可能性がありますが、どこかで301または302リダイレクトが発生し、GETに切り替わります。

これが事実であるかどうか確認するために$_SERVER['REQUEST_METHOD']を検査して下さい。

なぜこれが起こらないはずなのにそれでもなお起こるのかについてのよい議論については https://stackoverflow.com/a/19422232/109787 を見てください。

10
Legolas

配列の戻り値

 $data = json_decode(file_get_contents('php://input'), true);
3
umesh bhanderi

HTTP PECL拡張モジュールをインストールした場合は、ボディデータを文字列として取得するために http_get_request_body() 関数を使用できます。

3
shivanshu patel
3
linepogl

pecl/http 拡張機能がインストールされている場合は、これも使用できます。

$request = new http\Env\Request();
$request->getBody();
2
spinkus

http_get_request_body()は、ドキュメント http://php.net/manual/fa/function.http-get-request-body.php に従って、PUTおよびPOSTリクエストの本文を取得するために明示的に作られました

1
Yehuda Schwartz