$dummy = file_get_contents('http://example.com');
var_dump($http_response_header); // ←なにこれ?
PHPには、予め定義されている変数がいくつかあります。
有名どころとしては$_REQUEST
・$_SESSION
等のスーパーグローバル変数、PHPをコマンドライン実行した際に入ってくる$argc・$argvです。
そしてそれ以外にひとつだけ特殊な変数があり、HTTPラッパーを使うと唐突に$http_response_headerという変数が生えます。
非常にわかりにくいというか理解に苦しむ仕様なので、これを関数経由で取得するRFCが提出されました。
既に受理されており、PHP8.4から使用可能になります。
以下は該当のRFC、Add http_(get|clear)_last_response_headers() functionの紹介です。
PHP RFC: Add http_(get|clear)_last_response_headers() function
Introduction
PHPのストリーム層を通じてHTTPリクエストを実行したとき、すなわちHTTPラッパーを使用したときに、変数$http_response_headerがどこからともなく湧いて出てきます。
よくある例としてはfile_get_contents()を使ったときです。
$http_response_header
には、HTTPラッパー経由で実行したリクエストのHTTPヘッダが含まれます。
ローカルスコープに変数を生成するという動作は追加情報を得るための最もひどい方法のひとつであるため、$php_errormsgなど類似の機能は削除されつつあります。
この変数もPHP8.1で非推奨にしたいという話はありましたが、当時は適切な代替手段がなかったため提案の対象外になりました。
ここでは、$php_errormsg
を置き替えたerror_get_last()/error_clear_last()
と同様に、$http_response_header
を置き替える関数を提案します。
Motivation
関数を導入する主な目的は、変数$http_response_header
をいずれ削除するためです。
この変数を作成するためにエンジン関数zend_set_local_var_str()
が使われています。
$http_response_header
は、この関数とその兄弟zend_set_local_var()
を今なお使用している唯一の変数です。
さらにこの変数はopcacheやJIT環境では個別に特殊な処理が必要であるため、opcache下では挙動が変わってしまう可能性があります。
この機能の削除による影響については、Backward Incompatible Changesを参照してください。
Proposal
2つの関数http_get_last_response_header(): ?array
・http_clear_last_response_header(): void
を追加します。
http_get_last_response_header()
は、$http_response_header
と同じHTTPヘッダの内容を返します。
http_clear_last_response_header()
は、HTTPヘッダをクリアします。
Backward Incompatible Changes
このRFCではまだ$http_response_header
を非推奨にしないため、下位互換性のない変更点はありません。
この機能の使用状況をExakatで分析しました。
Composerパッケージ、OSSプロジェクト等900件以上を分析したところ、30のプロジェクトで65か所が見つかりました。
使用のほとんどはGuzzleやOauth等のライブラリに由来するものでした。
$http_response_header
が削除された場合のpolyfillは不可能ですが、以下のようにすることで同じコードを使い続けることができます。
$content = file_get_contents('http://example.com/');
if (function_exists('http_get_last_response_headers')) {
$http_response_header = http_get_last_response_headers();
}
この機能の使用頻度が少ないこと、互換のある記述が可能であること、エンジンやオプティマイザ開発の効率化を考えると、非推奨の段階を経ずに削除することも合理的かもしれません。
Version
PHP8.4。
Vote
投票期間は2024/01/29~2024/02/14、投票の2/3の賛成で受理されます。
本RFCは賛成15反対1の賛成多数で可決されました。
References
感想
この手の勝手に生える変数、昔はもっと存在していたのですが、register_globalsはPHP4.2で非推奨になり、$HTTP_RAW_POST_DATAはPHP5.6で非推奨になり、$php_errormsgもPHP7.2で非推奨になり、とどんどん片付けられつつあり、現在も残っているのはこの$http_response_headerと、コマンドライン実行時に入ってくる$argc・$argvだけです。
そして$http_response_header
もRFCのとおり、PHP9あたりで非推奨にされることは既定路線でしょう。
ということで最後まで残るのは$argc・$argv
です。
これらについては今のところどうこうする話は出ていないようですが、いずれは他と合わせてスーパーグローバル変数$_ARGC・$_ARGV
になるか、get_argc()
のような関数になるかもしれませんね。
あともうひとつ気になることとしては、どうして$GLOBALS
だけ_がついてないんだ。