我有一个PHP脚本,需要使用HTTP响应代码(状态代码)进行响应,例如HTTP 200 OK,或一些4XX或5XX代码。
如何在PHP中做到这一点?
我有一个PHP脚本,需要使用HTTP响应代码(状态代码)进行响应,例如HTTP 200 OK,或一些4XX或5XX代码。
如何在PHP中做到这一点?
Answers:
我刚刚发现了这个问题,并认为它需要一个更全面的答案:
从PHP 5.4开始,有三种方法可以实现此目的:
该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_sapi_name()
需要PHP 4.0.1
使用第一个变体时显然存在一些问题。我认为其中最大的一点是它是由PHP或Web服务器部分解析的,且文档记录不充分。
从4.3开始,该header
函数具有第3个自变量,可让您稍微舒适地设置响应代码,但使用它需要第一个自变量为非空字符串。这里有两个选择:
header(':', true, 404);
header('X-PHP-Response-Code: 404', true, 404);
我推荐第二个。第一个确实可以在我测试过的所有浏览器上运行,但是某些次要浏览器或网络爬网程序的标题行可能仅包含冒号,因此可能会出现问题。标头字段名称在第二位。当然,变体没有任何标准化形式,可以修改,我只是选择了一个描述性的名称。
该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;
}
}
headers_sent()
在调用之后并不总是正确的header()
吗?(2)在5.4世界中找到过类似http_response_text()的东西吗?至少旧的header()会影响状态代码后的文本。
headers_sent()
为真,如果因为内容已经发送而不能再添加任何标头,则不是,如果您添加了标头,则为@ BobStein-VisiBone (1)。(2)对不起,没有。其他语言则得到了更好的支持
http_response_code
(可能更一般地修改标题)在您完成echo
某些操作后不再起作用。希望能帮助到你。
不幸的是,我发现@dualed提供的解决方案存在各种缺陷。
使用substr($sapi_type, 0, 3) == 'cgi'
不能检测快速CGI。当使用PHP-FPM FastCGI Process Manager时,php_sapi_name()
返回fpm而不是cgi
Fasctcgi和php-fpm暴露了@Josh提到的另一个错误-使用header('X-PHP-Response-Code: 404', true, 404);
在PHP-FPM(FastCGI)下可以正常工作
header("HTTP/1.1 404 Not Found");
协议不是HTTP / 1.1(即“ HTTP / 1.0”)时可能会失败。必须使用来检测当前协议$_SERVER['SERVER_PROTOCOL']
(自PHP 4.1.0起可用
调用http_response_code()
结果导致异常行为时,至少有两种情况:
供您参考,这里有HTTP响应状态代码的完整列表(此列表包括IETF互联网标准和其他IETF RFC的代码。PHPhttp_response_code函数当前不支持其中的许多代码): http://en.wikipedia .org / wiki / List_of_HTTP_status_codes
您可以通过调用以下命令轻松测试此错误:
http_response_code(521);
服务器将发送“ 500 Internal Server Error” 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响应代码。
新的http_response_code()函数不能解决所有涉及的问题,但会带来更糟糕的情况,从而引入新的错误。
@dualed提供的“兼容性”解决方案无法正常工作,至少在PHP-FPM下如此。
@dualed提供的其他解决方案也存在各种错误。快速CGI检测无法处理PHP-FPM。必须检测到当前协议。
任何测试和评论表示赞赏。
从PHP 5.4开始,您可以使用http_response_code()
get和set标头状态代码。
这里有个例子:
<?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");
将消息部分(“确定”)替换为适当的消息,并将状态代码替换为相应的代码(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 Not Found标头。您必须重写它。这也将起作用:
define('WP_USE_THEMES', false);
require('../wp-blog-header.php');
header("HTTP/1.1 200 OK");
header("Status: 200 All rosy");
header("HTTP/1.1 200 OK");
http_response_code(201);
header("Status: 200 All rosy");
http_response_code(200); 因为测试警报404 https://developers.google.com/speed/pagespeed/insights/
如果您的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;
}
我们可以通过两个不同的环境从http_response_code获得不同的返回值:
在Web服务器环境中,如果您提供了响应代码,或者没有提供任何响应代码,则返回先前的响应代码,然后将打印当前值。默认值为200(确定)。
在CLI环境中,如果提供了响应代码,则将返回true;如果不提供任何response_code,则将返回false。
Web服务器环境的Response_code返回值的示例:
var_dump(http_respone_code(500)); // int(200)
var_dump(http_response_code()); // int(500)
响应代码返回值的CLI环境示例:
var_dump(http_response_code()); // bool(false)
var_dump(http_response_code(501)); // bool(true)
var_dump(http_response_code()); // int(501)
header('X-PHP-Response-Code: 404', true, 404);
确实可以在PHP-FPM(FastCGI)下正常工作