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以降では使えません。