3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ozvisionAdvent Calendar 2019

Day 19

$_POST は万能じゃなかった!(困って学ぶ日々の備忘録)

Posted at

痛い目に合いつつ学んだ内容をただ残していくだけの記事ですが、調べて日本語の記事があんまりなかったのでまずは簡単な内容でも助かる方がいるかも!と思い、公開。

タイトル通りですが、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 になるので、ある意味「自由に何でもできる状態」ではあります。

今回参考になった記事

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?