PHPではリクエストからパラメータを取得する場合$_GET
や$_POST
が用意されていますが、これはContent-Type
がapplication/x-www-form-urlencoded
の場合の話です。
JSON-RPC
のようにContent-Type
がapplication/json
の場合にパラメーターを取得するにはPHPに頼らずリクエストボディーのJSONを自力でパースする必要があります。
stream を使う
リクエストボディーを取得するにはWEBサーバとして動かす場合は php://input
を使います。
var_dump(file_get_contents('php://input'));
下記を短く書いています。
$stream = fopen('php://input');
$data = stream_get_contents($stream);
fclose($stream);
var_dump($data);
コード
リクエストボディーのJSONをパースしてダンプするスクリプトを test.php
としてファイルにします。
<?php
var_dump(json_decode(file_get_contents('php://input'), true));
動作確認
PHPのビルトインサーバでホストし、curlでtest.phpを呼び出します。
$ php -S localhost:8080 # test.php の存在するディレクトリで実行する
$ curl -X POST \
-d '{"hello":"world", "こんにちは":"世界"}' \
-H "Content-Type: application/json" \
http://localhost:8080/test.php
array(2) {
["hello"]=>
string(5) "world"
["こんにちは"]=>
string(6) "世界"
}
例ではapplication/json
が送られてくる場合を仮定しましたが、application/x-www-form-urlencoded
でも、パースされていない生データを取得することができます。 (もちろんjson_decodeしてはいけません)
ヒント
php://input
と php://stdin
の違いがよくわかっていなくて、 php://stdin
を使用すると、ブロッキングしてしまってWEBサーバがレスポンスを返さなくなります。CLIだとエンターを押すまでブロッキングするからでしょうかね。
アプリケーションサーバとして使う場合はphp://input
を使いましょう。そしてブロッキングしてるWEBサーバは再起動しましょう。
CLIの場合はSTDIN
定数やphp://stdin
を使うのだと思います。
※ STDIN
はfopen('php://stdin')
と等価です
$HTTP_RAW_POST_DATA 変数を使う
PHP7 より前は $HTTP_RAW_POST_DATA
に生のPOSTデータがセットされていましたが、PHP7以降では使えません。