HTTP 200 OK や 4XX または 5XX コードなどの HTTP 応答コード (ステータス コード) で応答する必要がある PHP スクリプトがあります。
PHPでこれを行うにはどうすればよいですか?
HTTP 200 OK や 4XX または 5XX コードなどの HTTP 応答コード (ステータス コード) で応答する必要がある PHP スクリプトがあります。
PHPでこれを行うにはどうすればよいですか?
この質問を見つけたところ、より包括的な回答が必要だと思いました。
PHP 5.4 では、これを実現するための 3 つの方法があります。
このheader()
関数には、HTTP 応答行を検出し、それをカスタムのものに置き換えることができる特別なユース ケースがあります。
header("HTTP/1.1 200 OK");
ただし、これには (Fast)CGI PHP の特別な処理が必要です。
$sapi_type = php_sapi_name();
if (substr($sapi_type, 0, 3) == 'cgi')
header("Status: 404 Not Found");
else
header("HTTP/1.1 404 Not Found");
注: HTTP RFCによると、理由フレーズは (標準に準拠する) 任意のカスタム文字列にすることができますが、クライアントの互換性のために、そこにランダムな文字列を配置することはお勧めしません。
注: PHP 4.0.1php_sapi_name()
が必要です
その最初のバリアントを使用する場合、明らかにいくつかの問題があります。私が思う最大の問題は、PHP または Web サーバーによって部分的に解析され、文書化が不十分であることです。
4.3 以降、header
関数には 3 番目の引数があり、応答コードをある程度快適に設定できますが、これを使用するには、最初の引数を空でない文字列にする必要があります。次の 2 つのオプションがあります。
header(':', true, 404);
header('X-PHP-Response-Code: 404', true, 404);
私は2番目のものをお勧めします。1 つ目は、私がテストしたすべてのブラウザーで動作しますが、一部のマイナーなブラウザーまたは Web クローラーでは、コロンのみを含むヘッダー行に問題がある場合があります。2 番目のヘッダー フィールド名。バリアントはもちろん標準化されておらず、変更することもできます。うまくいけばわかりやすい名前を選んだだけです。
このhttp_response_code()
関数は PHP 5.4 で導入され、非常に簡単になりました。
http_response_code(404);
それで全部です。
これは、5.4 未満の互換性が必要であるが「新しい」http_response_code
関数の機能が必要なときに作成した関数です。PHP 4.3 は十分な下位互換性を備えていると思いますが、わかりません...
// For 4.3.0 <= PHP <= 5.4.0
if (!function_exists('http_response_code'))
{
function http_response_code($newcode = NULL)
{
static $code = 200;
if($newcode !== NULL)
{
header('X-PHP-Response-Code: '.$newcode, true, $newcode);
if(!headers_sent())
$code = $newcode;
}
return $code;
}
}
残念ながら、@dualed によって提示されたソリューションにはさまざまな欠陥があることがわかりました。
substr($sapi_type, 0, 3) == 'cgi'
高速な CGI を検出するには、使用するだけでは十分ではありません。PHP-FPM FastCGI Process Manager を使用している場合、php_sapi_name()
cgi ではなく fpm を返します
Fasctcgi と php-fpm は、@Josh によって言及された別のバグを公開します - header('X-PHP-Response-Code: 404', true, 404);
PHP-FPM (FastCGI) では using は正しく動作します
header("HTTP/1.1 404 Not Found");
プロトコルが HTTP/1.1 (つまり、「HTTP/1.0」) でない場合、失敗する可能性があります。現在のプロトコルは$_SERVER['SERVER_PROTOCOL']
(PHP 4.1.0 以降で利用可能)を使用して検出する必要があります
http_response_code()
呼び出しによって予期しない動作が発生するケースが少なくとも 2 つあります。
参考までに、HTTP 応答ステータス コードの完全なリストを以下に示します (このリストには、IETF インターネット標準や他の IETF RFC のコードが含まれています。現在、それらの多くは PHP の http_response_code 関数ではサポートされていません): http://en.wikipedia .org/wiki/List_of_HTTP_status_codes
次のように呼び出すことで、このバグを簡単にテストできます。
http_response_code(521);
サーバーは「500 内部サーバー エラー」HTTP 応答コードを送信し、たとえばカスタム クライアント アプリケーションがサーバーを呼び出して追加の HTTP コードを予期している場合、予期しないエラーが発生します。
私の解決策(4.1.0以降のすべてのPHPバージョン):
$httpStatusCode = 521;
$httpStatusMsg = 'Web server is down';
$phpSapiName = substr(php_sapi_name(), 0, 3);
if ($phpSapiName == 'cgi' || $phpSapiName == 'fpm') {
header('Status: '.$httpStatusCode.' '.$httpStatusMsg);
} else {
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
header($protocol.' '.$httpStatusCode.' '.$httpStatusMsg);
}
結論
http_response_code() 実装は、すべての HTTP 応答コードをサポートしていないため、指定された HTTP 応答コードを同じグループの別のコードで上書きする場合があります。
新しい http_response_code() 関数は、関連するすべての問題を解決するわけではありませんが、新しいバグを導入して事態を悪化させます。
@dualed が提供する「互換性」ソリューションは、少なくとも PHP-FPM では期待どおりに機能しません。
@dualed が提供する他のソリューションにもさまざまなバグがあります。高速 CGI 検出は、PHP-FPM を処理しません。現在のプロトコルを検出する必要があります。
テストやコメントは大歓迎です。
PHP 5.4 以降http_response_code()
では、ヘッダー ステータス コードの取得と設定に使用できます。
ここに例があります:
<?php
// Get the current response code and set a new one
var_dump(http_response_code(404));
// Get the new response code
var_dump(http_response_code());
?>
php.net のこの関数のドキュメントは次のとおりです。
出力バッファリングを使用していない場合は、本文の出力の前にこの行を追加します。
header("HTTP/1.1 200 OK");
メッセージ部分 (「OK」) を適切なメッセージに置き換え、ステータス コードを適切なコード (404、501 など) に置き換えます。
ヘッダー機能付き。最初のパラメーターのセクションに例があります。