我有一个PHP脚本,需要使用HTTP响应代码(status-codes)进行响应,例如HTTP200OK,或者一些4xx或5xx代码。

我怎样才能在PHP中做到这一点?

有帮助吗?

解决方案

我刚刚发现这个问题并认为它需要一个更全面的答案:

php 5.4 有三种方法来实现这一点:

自己组装响应代码(php>= 4.0)

header() 函数具有检测HTTP响应行的特殊用例,并允许您使用a替换自定义一个

header("HTTP/1.1 200 OK");
. 然而,这需要对(快)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_sapi_name() 需要 php 4.0.1

第3个参数标题函数(php>= 4.3)

使用该第一变体时显然存在一些问题。我认为最大的是它是PHP或Web服务器的部分解析,并记录不足。

自4.3以来,header函数有一个第三个参数,允许您稍微舒适地设置响应代码,但使用它需要第一个参数是非空字符串。以下是两个选项:

header(':', true, 404);
header('X-PHP-Response-Code: 404', true, 404);
.

我推荐第2个。第一个在所有测试的所有浏览器上进行工作,但一些小型浏览器或Web爬虫器可能会出现一个只包含冒号的标题线。 2nd中的标题字段名称。变体当然不是以任何方式标准化,可以修改,我只是选择了一个希望的描述性名称。

http_response_code函数(php>= 5.4)

http_response_code() 功能是在PHP 5.4中引入的,它使东西很多更容易。

http_response_code(404);
.

就是这样。

兼容性

此处是我在5.4以下需要兼容性时烹饪的函数,但希望“新建”生成函数函数的功能。我相信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提供的解决方案存在各种缺陷。

  1. 使用 substr($sapi_type, 0, 3) == 'cgi' 无法检测快速CGI。使用PHP-FPM FastCGI进程管理器时, php_sapi_name() 返回fpm而不是cgi

  2. Fasctcgi和php-fpm暴露了@Josh提到的另一个bug-using header('X-PHP-Response-Code: 404', true, 404); 在PHP-FPM(FastCGI)下是否正常工作

  3. header("HTTP/1.1 404 Not Found"); 当协议不是HTTP/1.1时可能会失败(即'HTTP/1.0')。当前协议必须使用 $_SERVER['SERVER_PROTOCOL'] (从PHP4.1.0开始提供

  4. 打电话时至少有2种情况 http_response_code() 导致意外行为:

    • 当PHP遇到它不理解的HTTP响应代码时,PHP会将代码替换为它从同一组中知道的代码。例如,"521Web服务器关闭"被"500内部服务器错误"取代。来自其他组2xx,3xx,4xx的许多其他不常见的响应代码都以这种方式处理。
    • 在具有php-fpm和nginx的服务器上http_response_code()函数可能会按预期更改代码,但不会更改消息。例如,这可能会导致奇怪的"404OK"标头。这个问题在PHP网站上也被用户评论提到 http://www.php.net/manual/en/function.http-response-code.php#112423

这里有HTTP响应状态代码的完整列表供您参考(此列表包括来自IETF internet标准以及其他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您可以使用for get和set header状态代码的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

在正文的任何输出之前添加此行,如果您不使用输出缓冲。

header("HTTP/1.1 200 OK");
.

用相应的消息替换消息部分('确定'),以及适当的代码的状态代码(404,501等)

如果您在这里因为Wordpress提供404在加载环境时,这应该解决问题:

define('WP_USE_THEMES', false);
require('../wp-blog-header.php');
status_header( 200 );
//$wp_query->is_404=false; // if necessary
.

问题是由于它发送状态:404找不到标题。你必须覆盖这一点。 这也将有效:

define('WP_USE_THEMES', false);
require('../wp-blog-header.php');
header("HTTP/1.1 200 OK");
header("Status: 200 All rosy");
.

标头功能。在它需要的第一个参数上有一个例子。

如果您的PHP版本不包括此功能:

<?php

function http_response_code($code = NULL) {
        if ($code !== NULL) {
            switch ($code) {
                case 100: $text = 'Continue';
                    break;
                case 101: $text = 'Switching Protocols';
                    break;
                case 200: $text = 'OK';
                    break;
                case 201: $text = 'Created';
                    break;
                case 202: $text = 'Accepted';
                    break;
                case 203: $text = 'Non-Authoritative Information';
                    break;
                case 204: $text = 'No Content';
                    break;
                case 205: $text = 'Reset Content';
                    break;
                case 206: $text = 'Partial Content';
                    break;
                case 300: $text = 'Multiple Choices';
                    break;
                case 301: $text = 'Moved Permanently';
                    break;
                case 302: $text = 'Moved Temporarily';
                    break;
                case 303: $text = 'See Other';
                    break;
                case 304: $text = 'Not Modified';
                    break;
                case 305: $text = 'Use Proxy';
                    break;
                case 400: $text = 'Bad Request';
                    break;
                case 401: $text = 'Unauthorized';
                    break;
                case 402: $text = 'Payment Required';
                    break;
                case 403: $text = 'Forbidden';
                    break;
                case 404: $text = 'Not Found';
                    break;
                case 405: $text = 'Method Not Allowed';
                    break;
                case 406: $text = 'Not Acceptable';
                    break;
                case 407: $text = 'Proxy Authentication Required';
                    break;
                case 408: $text = 'Request Time-out';
                    break;
                case 409: $text = 'Conflict';
                    break;
                case 410: $text = 'Gone';
                    break;
                case 411: $text = 'Length Required';
                    break;
                case 412: $text = 'Precondition Failed';
                    break;
                case 413: $text = 'Request Entity Too Large';
                    break;
                case 414: $text = 'Request-URI Too Large';
                    break;
                case 415: $text = 'Unsupported Media Type';
                    break;
                case 500: $text = 'Internal Server Error';
                    break;
                case 501: $text = 'Not Implemented';
                    break;
                case 502: $text = 'Bad Gateway';
                    break;
                case 503: $text = 'Service Unavailable';
                    break;
                case 504: $text = 'Gateway Time-out';
                    break;
                case 505: $text = 'HTTP Version not supported';
                    break;
                default:
                    exit('Unknown http status code "' . htmlentities($code) . '"');
                    break;
            }
            $protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');
            header($protocol . ' ' . $code . ' ' . $text);
            $GLOBALS['http_response_code'] = $code;
        } else {
            $code = (isset($GLOBALS['http_response_code']) ? $GLOBALS['http_response_code'] : 200);
        }
        return $code;
    }
.

We can get different return value from http_response_code via the two different environment:

  1. Web Server Environment
  2. CLI environment

At the web server environment, return previous response code if you provided a response code or when you do not provide any response code then it will be print the current value. Default value is 200 (OK).

At CLI Environment, true will be return if you provided a response code and false if you do not provide any response_code.

Example of Web Server Environment of Response_code's return value:

var_dump(http_respone_code(500)); // int(200)
var_dump(http_response_code()); // int(500)

Example of CLI Environment of Response_code's return value:

var_dump(http_response_code()); // bool(false)
var_dump(http_response_code(501)); // bool(true)
var_dump(http_response_code()); // int(501)
header("HTTP/1.1 200 OK");
http_response_code(201);
header("Status: 200 All rosy");

http_response_code(200); not work because test alert 404 https://developers.google.com/speed/pagespeed/insights/

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top