axiosでPOSTしたデータがサーバのPHPの$_POSTで取得できない

axiosでpostしたオブジェクトはjson形式でサーバに送られる。content-typeはapplication/jsonで送られる。PHPはこれを$_POSTに入れない。通常のhtmlのformで送られるデータとはcontent-typeも中身も違う。このjsonで送られたデータをどうやってPHPで取得すればいいか。

axiosでformDataを送る

1つの解決法はaxiosでPOSTするときにフォーム形式で送る方法。これはオブジェクトの代わりにformDataを設定する方法とcontent-typeを設定する方法があるようだがここでは考えずサーバで対応する方法を考える。

PHPでjsonを受け取る

ここではapache2+PHPのサーバを考える。その前にクライアントからポストしたデータ(HTTPのボディ)はどのように扱われるのだろうかをはっきりさせたい。

PHPのマニュアルによるとcontent-typeがapplication/x-www-form-urlencodedmultipart/form-dataの場合は$_POSTにデータが入るらしい。マルチパートというのはもともとは1つのファイルに複数のファイルを埋め込む方式でメールなどで添付ファイルを送るときに使われたものだと思う。境界となる長い文字列を設定し、それでファイルを分割する。大きいファイルを送るとき、あるいは単にファイルをおくるときはブラウザはこの形式を使うのかもしれない。あるいはバイナリを送りたいときエンコードを指定して送るから必要になるのかもしれない。

いずれにしろ$_POSTにデータが入るのはこの2つの場合だけなのでapplication/jsonの場合は$_POSTには入らない。ではどこへ行くのか?あるいは単に捨てられてしまうのだろうか。

php://input

結論を言うとここにあるように、php://inputに行くらしい。これはPHPにおいて標準入力を表すときにphp://stdinなどと書くが、php://inputはPHPによってHTTPボディからの入力にリダイレクトされていてPHPスクリプトからはここから読み込めばHTTPボディが取得できることになる。

jsonの取得

今回のデータはjson形式なのであとはこれを$_POSTに変換してあげればその他のコードは変更せずに動くはず。

元のサイトのコードが少しおかしかったので修正した。

以下のようにpostmanで送るとPHPで取得できた。