301

HTTP 200 OK や 4XX または 5XX コードなどの HTTP 応答コード (ステータス コード) で応答する必要がある PHP スクリプトがあります。

PHPでこれを行うにはどうすればよいですか?

4

8 に答える 8

525

この質問を見つけたところ、より包括的な回答が必要だと思いました。

PHP 5.4 では、これを実現するための 3 つの方法があります。

自分で応答コードを組み立てる (PHP >= 4.0)

この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()が必要です

ヘッダー関数の 3 番目の引数 (PHP >= 4.3)

その最初のバリアントを使用する場合、明らかにいくつかの問題があります。私が思う最大の問題は、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()関数は 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;
    }
}
于 2012-08-18T12:18:01.163 に答える
49

残念ながら、@dualed によって提示されたソリューションにはさまざまな欠陥があることがわかりました。

  1. substr($sapi_type, 0, 3) == 'cgi'高速な CGI を検出するには、使用するだけでは十分ではありません。PHP-FPM FastCGI Process Manager を使用している場合、php_sapi_name()cgi ではなく fpm を返します

  2. Fasctcgi と php-fpm は、@Josh によって言及された別のバグを公開します - header('X-PHP-Response-Code: 404', true, 404);PHP-FPM (FastCGI) では using は正しく動作します

  3. header("HTTP/1.1 404 Not Found");プロトコルが HTTP/1.1 (つまり、「HTTP/1.0」) でない場合、失敗する可能性があります。現在のプロトコルは$_SERVER['SERVER_PROTOCOL'](PHP 4.1.0 以降で利用可能)を使用して検出する必要があります

  4. http_response_code()呼び出しによって予期しない動作が発生するケースが少なくとも 2 つあります。

    • PHP が理解できない HTTP 応答コードに遭遇すると、PHP はそのコードを同じグループから既知のものに置き換えます。たとえば、「521 Web サーバーがダウンしています」は「500 内部サーバー エラー」に置き換えられます。他のグループ 2xx、3xx、4xx からの他の多くの珍しい応答コードは、この方法で処理されます。
    • php-fpm および nginx http_response_code() 関数を使用するサーバーでは、コードは期待どおりに変更される可能性がありますが、メッセージは変更されません。これにより、たとえば、奇妙な「404 OK」ヘッダーが表示される場合があります。この問題は、ユーザー コメントhttp://www.php.net/manual/en/function.http-response-code.php#112423によって PHP Web サイトでも言及されています。

参考までに、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 を処理しません。現在のプロトコルを検出する必要があります。

テストやコメントは大歓迎です。

于 2014-04-21T04:46:31.280 に答える
29

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 のこの関数のドキュメントは次のとおりです。

http_response_code

于 2017-01-06T15:54:17.747 に答える
12

出力バッファリングを使用していない場合は、本文の出力の前にこの行を追加します。

header("HTTP/1.1 200 OK");

メッセージ部分 (「OK」) を適切なメッセージに置き換え、ステータス コードを適切なコード (404、501 など) に置き換えます。

于 2010-07-15T18:27:02.540 に答える
5

ヘッダー機能付き。最初のパラメーターのセクションに例があります。

于 2010-07-15T18:26:35.037 に答える