PHPでHTTPレスポンスヘッダーを自由に制御(できなかった)
Posted: Updated:
PHPでHTTPレスポンスヘッダーを制御しようと思うと...
PHP Modify HTTP Headers (Examples)
上記のように、header関数だらけで懇切丁寧に上書きすることになります。
ただ、これだと勝手に差し込まれている分のヘッダーが明示されないし、何だかちゃんとコントロールしてる感に欠けるのでヤだなーと思ってました。前にHTTPクライアントを実装したときに、fsockopenからfwriteで、リクエストをカキコカキコしていた覚えから、レスポンスヘッダーもイチからカキコカキコできないかと思い、調べてみた次第。
入出力ストリームからアクセスできないかな、と思ってトライ
PHP 入出力ストリーム でheaderを書いたことにならないかと期待してそれぞれ試してみました。
※ 今回はきっと、知ってる・分かってる方からしたら「あったりまえじゃん」的な内容なのだと思います。言い訳 lol
php://output
<?php $out = fopen('php://output', 'w'); fwrite($out, "HTTP/1.1 418 I'm a Teapot\r\n"); fclose($out); ?>
HTTP/1.1 200 OK Date: Mon, 25 Oct 2010 09:49:00 GMT Server: Apache X-Powered-By: PHP/5.2.14 Vary: Accept-Encoding,User-Agent Content-Encoding: gzip Content-Length: 57 Connection: close Content-Type: text/html; charset=UTF-8 HTTP/1.1 418 I'm a Teapot
レスポンスボディ部分に書き込まれてしまいました。
php://stdout
<?php $out = fopen('php://stdout', 'w'); fwrite($out, "HTTP/1.1 418 I'm a Teapot\r\n"); fclose($out); ?>
HTTP/1.1 200 OK Date: Mon, 25 Oct 2010 09:50:03 GMT Server: Apache X-Powered-By: PHP/5.2.14 Vary: Accept-Encoding,User-Agent Content-Encoding: gzip Content-Length: 30 Connection: close Content-Type: text/html; charset=UTF-8
ボディにもいかないあたり、標準出力の名の通り、php://stderr等と合わせてCLIやらエラーログ用の受け口だと思います。(詳細は未確認)
ob ( output buffering ? ) 系関数にも期待しましたが
この関数は出力のバッファリングをオンにします。 出力のバッファリングを有効にすると、 (ヘッダ以外の) スクリプトからの出力は実際には行われず、 代わりに内部バッファに保存されます。 PHP: ob_start - Manual
ヘッダ以外の出力、とのことなので、phpにおけるheader関数以外のoutputは、やっぱりボディの話のようです。
参考までに、PhpTipsに書かれている内容を流し見ても、やはりそのような結論に至るニュアンスがチラホラ。うーん残念。
オマケ php の PUTメソッドサポート
今回のHTTPヘッダー完全制御の道筋があるんじゃないかと、勝手に期待してしまったのは以下の項目を読んでいる最中でした。
PHP: PUT method support - Manual
<?php $input = @file_get_contents('php://input'); @file_put_contents($path, $input); ?>
一通り試してみてから見直してみると、これでPUTのリクエストボディが input だって言うのだから、そりゃ output はレスポンスボディだよね、と納得。
オマケ2 出力予定なheaderの取得
どっちも似たような機能の関数ですが、前者はPHP5から。リクエストヘッダの最初の行は、双方のリストアップの対象ではないみたい。どういう意味でなんだろう。
あと、PHPで明示していない&リストアップもされていないヘッダが付与されているのは、Apacheが勝手につけてる分だろうか。PHP側で書いていなければ、Apacheがhttpd.conf等の設定如何で、付与してると勝手に推測。この辺のミドルウェア(?)周りの細かい挙動は、理解浅いなー。
<?php header("HTTP/1.1 418 I'm a Teapot"); header("Content-Encoding: hogehoge"); var_dump(headers_list()); var_dump(apache_response_headers()); ?>
HTTP/1.1 418 I'm a Teapot Date: Mon, 25 Oct 2010 10:07:18 GMT Server: Apache X-Powered-By: PHP/5.2.14 Content-Encoding: none Vary: User-Agent Content-Length: 140 Connection: close Content-Type: text/html; charset=UTF-8 array(2) { [0]=> string(24) "X-Powered-By: PHP/5.2.14" [1]=> string(22) "Content-Encoding: hogehoge" } array(2) { ["X-Powered-By"]=> string(10) "PHP/5.2.14" ["Content-Encoding"]=> string(8) "hogehoge" }
今回は以上。ではでは。