次のように、phpページにPOSTとして送信します。
{a:1}
これはリクエストの本文です(POSTリクエスト)。
PHPでは、その値を抽出するために何をしなければなりませんか?
var_dump($_POST);
解決策ではなく、機能していません。
次のように、phpページにPOSTとして送信します。
{a:1}
これはリクエストの本文です(POSTリクエスト)。
PHPでは、その値を抽出するために何をしなければなりませんか?
var_dump($_POST);
解決策ではなく、機能していません。
回答:
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ディレクティブに依存しないため、代わりにphp:// inputを使用することをお
$HTTP_RAW_POST_DATA
勧めします。さらに、$HTTP_RAW_POST_DATA
デフォルトでデータが設定されていない場合、 always_populate_raw_post_dataをアクティブにする代わりに、メモリをあまり消費しない可能性があります。php:// inputはenctype = "multipart / form-data"では使用できません。
特にphp://input
、Web SAPIでストリームにアクセスする方法に関係なく、ストリームはシークできないことに注意してください。これは、一度だけ読み取ることができることを意味します。大きな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リクエストエンティティの本文を1回読み取るだけで十分です。アプリが何をすべきかを理解している間、クライアントを1日中待たせないでください。
php:// inputは、Content-Type: multipart/form-data
ヘッダーを指定するリクエスト(enctype="multipart/form-data"
HTMLフォーム)では使用できないことに注意してください。これは、PHPがフォームデータをすでに$_POST
スーパーグローバルに解析しているためです。
php://input
はapplication/x-www-form-urlencoded
(をmultipart/form-data
php://input
。したがって、(高速)CGI構成でstream_get_contents(STDIN)
は機能しませんが、機能しfile_get_contents("php://input")
ます。
配列の戻り値
$data = json_decode(file_get_contents('php://input'), true);
$data
連想配列をループして、各値が希望どおりにエンコードされているかどうかを確認する必要があります。「ストリームからデータ型へ」の見方は単純化されているかもしれませんが、ストリームフィルターを使用して「ストリーム形式」でエンコードする場合ほど効率的ではありません。エンコーディングの問題を処理せず、単純にサニタイズと検証を行っている場合、ステップがありません。
空の可能性のある理由$_POST
は、リクエストがでないPOST
か、POST
もうないことです...ポストとして開始された可能性がありますが301
、に302
リダイレクトされたか、リダイレクトされましたGET
!
点検$_SERVER['REQUEST_METHOD']
これが事実であるかどうかをチェックします。
これが発生してはならないのに発生する理由については、https://stackoverflow.com/a/19422232/109787を参照してください。
POST
が、調べてみるとそうでしたGET
。/
URLの最後にを追加すると、POSTが表示され始めました。おかしい!
変数を確認してください$HTTP_RAW_POST_DATA
php://input
です。$HTTP_RAW_POST_DATA
では使用できませんenctype="multipart/form-data"
。
pecl / http拡張機能がインストールされている場合は、これも使用できます。
$request = new http\Env\Request();
$request->getBody();
function getPost()
{
if(!empty($_POST))
{
// when using application/x-www-form-urlencoded or multipart/form-data as the HTTP Content-Type in the request
// NOTE: if this is the case and $_POST is empty, check the variables_order in php.ini! - it must contain the letter P
return $_POST;
}
// when using application/json as the HTTP Content-Type in the request
$post = json_decode(file_get_contents('php://input'), true);
if(json_last_error() == JSON_ERROR_NONE)
{
return $post;
}
return [];
}
print_r(getPost());
json_last_error() == JSON_ERROR_NONE
でfalse
、空の配列が返されるべきであること。誰かがXMLまたはYAMLを送信した場合はどうなりますか?Content-Typeのテストを追加し、そこから進みます。
$_SERVER
確認に役立つ値については、スーパーグローバルを参照してください。
http_get_request_body()
ドキュメントhttp://php.net/manual/fa/function.http-get-request-body.phpのとおり、ボディPUT
とPOST
リクエストを取得するために明示的に作成されました
$_POST
スーパーグローバル経由では利用できないため、スクリプトに送信された生の入力データにアクセスする方法はほとんどわかりません。PHPには対応するスーパーグローバルがないため、これは(特に)PUTリクエストの場合にも当てはまります。