概要
HTTP GET と POST 以外のメソッドに対するスーパーグローバル変数の導入や $_POST
を改善すべきかという PHP Internals の議論を読みました。以前の議論のリンクがまとまっているだけでなく、スーパーグローバル変数および HTTP 通信の仕様をどのように学ぶのかの情報がまとまっているので、記録に残しておくことにしました。同時に PSR-7 以降の議論についても記載しました。
スーパーグローバル変数の名前
$_GET
$_GET
は名前だけでは HTTP GET メッセージをあらわすものとして考えてしまいがちですが、実際には URI クエリパラメーターであり、GET リクエスト以外にも使うことができます。
$_POST
$_POST
はリクエストボディをあらわしますが、Content-Type
ヘッダーの値が x-www-form-urlencoded
もしくは multipart/form-data
であるときにかぎられます。たとえば Content-Type
ヘッダーの値が application/json
である場合には読み込み専用のストリーム (php://input
) を利用する必要があります。
apfd (Always Populate Form Data) エクステンションを導入すれば、HTTP メッセージの Content-Type
の値が multipart/form-data
もしくは application/x-www-form-urlencoded
であれば、HTTP メソッドの種類に関わらず、スーパーグローバル変数に投入されるようになります。
json_post エクステンションを導入すれば、Content-Type
の値が application/json
と text/json
の HTTP メッセージは $_POST
に投入されます。
スーパーグローバル変数の弊害
PSR-7 のメタドキュメントにまとめられています。
規約よりも実装
Go のように Request、Response と Logger が PHP の標準クラスとして導入できないだろうかという Symfony の開発者のツイートが共感を集めました。
相互運用性のために PSR-7 を採用するプロジェクトが増えてきているものの、PSR-7 以前から存在するプロジェクトの立場から見れば、後方互換性を捨てて PSR-7 を採用して得られるメリットが少ないからです。
Symfony の場合、HttpFoundation コンポーネントは Laravel や Drupal など大きなプロジェクトに採用されています。
以前 pecl_http を PHP の標準クラスとして採用するかの投票がありましたが、否決に終わりました。
なお、PSR のインターフェイスの PECL エクステンション (php-psr) も公開されており、実装の学習教材になるでしょう。
スーパーグローバル変数をラップしたクラスの標準化の提案
標準クラス導入の RFC (Server-Side Request and Response Objects) が2016年12月に公開されました。RFC の作者 (Paul M. Jones さん) は PSR-7 との違いについて記事を公開しています。記事によると、主要な関心はリクエスト関連のスーパーグローバル変数および、レスポンス関連のグローバル関数をオブジェクトにカプセル化して、オブジェクト指向のプログラミングスタイルで扱うことができないか?とのことです。