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"
}
今回は以上。ではでは。