痛い目に合いつつ学んだ内容をただ残していくだけの記事ですが、調べて日本語の記事があんまりなかったのでまずは簡単な内容でも助かる方がいるかも!と思い、公開。
タイトル通りですが、GET/POST で送られてくるデータを受け取る時は何もかも $_POST
や $_GET
で受け取ってしまえばいい、わけではないのです。
長い前書きは抜きにして、今日は「PHP php://input
と $_GET / $_POST
の違い、使い分け」について最近ちょっと困った結果学んだ情報を軽く整理してみました。
$_POST
は万能じゃない
受け取れる情報の量の許容範囲が $_GET
よりあるからといって便利に思われがちですが、そうではにないことを最近実感した。
なんと・・・受信する殆どのデータが問題なのに、たま~にだけなぜか文字列が変なところで途切れたりして、構造が壊れ化けてしまうという・・・
ちょっと調べたら:
- XMLの受信
- JQueryからのAjaxリクエスト
には向いていないという。
今まであんまり意識せずにフレームワークのInputクラス(つまり、さらなる$_POSTラッパー)を使ったりしていましたが、本来は用途に応じて使い分ける必要があるとわかりました。
$_POSTを使って良いケース
以下のコンテンツタイプのみ、phpのラッパーである $_POST は良い仕事をするという大前提があるようです。これは「すべてのユーザーエージェントによってサポート対象であるコンテンツタイプだから」であって、それらのみが保証されているということのようです。
- application/x-www-form-urlencoded
- multipart/form-data
HTMLフォームで送信できる内容に限って使うイメージを持てば安全かなと思います。
ちなみに、私の場合はヘッダーが「application/x-www-form-urlencoded」で送られてきていた xml も化けてしまったので、ヘッダーのみで安心するのもちょっと厳しい気がします。
$_POSTを避けたほうがいいケース
- JSON を送信するとき(コンテンツタイプが application/json )
- xml を送信するとき(コンテンツタイプが application/xml )
- YAML を送信するとき(コンテンツタイプが application/yaml )
上記(というか、使って良いケース以外!)の場合 $_POST に格納されたデータが壊れるケースが多いようです。壊れからも様々で、最初はただ「うまくURLデコードできないかな?」と思ってしまうレベルだったりします。
他順なデータでテストしても問題ないのに、ちょっと特殊な文字が含まれ送られてきた分だけ文字化けして、結局形式が壊れて例えば XML としてパースできないデータになってしまう場合がります。
$_POST が使えない場合は?
php://input
から生のデータを引っ張り出す。
ただし、この場合は $_POST の恩恵(データをURLデコードしてくれちゃったり、配列にしてくれるあたり)が受けない分、全部自分で実装しないといけない。
送られてくるデータは、ただの(おそらくURLエンコードまたはRAW URLエンコードされた) string になるので、ある意味「自由に何でもできる状態」ではあります。
今回参考になった記事