我有一个PHP脚本,需要使用HTTP响应代码(状态代码)做出响应,如HTTP 200 OK,或一些4XX或5XX代码。

如何在PHP中做到这一点?


当前回答

如果你在这里是因为Wordpress在加载环境时给出404错误,这应该可以解决这个问题:

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

该问题是由于它发送一个状态:404 Not Found头。你必须重写它。 这也可以:

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

其他回答

如果你在这里是因为Wordpress在加载环境时给出404错误,这应该可以解决这个问题:

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

该问题是由于它发送一个状态:404 Not Found头。你必须重写它。 这也可以:

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

从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

在不使用输出缓冲的情况下,在body的任何输出之前添加这一行。

header("HTTP/1.1 200 OK");

将消息部分('OK')替换为适当的消息,并将状态代码替换为适当的代码(404、501等)

使用header函数。在第一个参数小节中有一个例子。

不幸的是,我发现@dualed提出的解决方案有各种缺陷。

Using substr($sapi_type, 0, 3) == 'cgi' is not enogh to detect fast CGI. When using PHP-FPM FastCGI Process Manager, php_sapi_name() returns fpm not cgi Fasctcgi and php-fpm expose another bug mentioned by @Josh - using header('X-PHP-Response-Code: 404', true, 404); does work properly under PHP-FPM (FastCGI) header("HTTP/1.1 404 Not Found"); may fail when the protocol is not HTTP/1.1 (i.e. 'HTTP/1.0'). Current protocol must be detected using $_SERVER['SERVER_PROTOCOL'] (available since PHP 4.1.0) There are at least 2 cases when calling http_response_code() result in unexpected behaviour:

When PHP encounter an HTTP response code it does not understand, PHP will replace the code with one it knows from the same group. For example "521 Web server is down" is replaced by "500 Internal Server Error". Many other uncommon response codes from other groups 2xx, 3xx, 4xx are handled this way. On a server with php-fpm and nginx http_response_code() function MAY change the code as expected but not the message. This may result in a strange "404 OK" header for example. This problem is also mentioned on PHP website by a user comment http://www.php.net/manual/en/function.http-response-code.php#112423

这里有HTTP响应状态代码的完整列表供您参考(该列表包括来自IETF互联网标准以及其他IETF rfc的代码。其中许多目前不支持PHP http_response_code函数):http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

你可以通过调用:

http_response_code(521);

如果您有一个自定义客户端应用程序需要额外的HTTP代码,服务器将发送“500 Internal server Error”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响应代码。

新的http_response_code()函数并不能解决所有涉及的问题,反而会引入新的错误。

@dualed提供的“兼容性”解决方案并没有像预期的那样工作,至少在PHP-FPM下是这样。

@dualed提供的其他解决方案也有各种bug。快速CGI检测不处理PHP-FPM。必须检测当前协议。

感谢任何测试和评论。