У меня есть PHP-скрипт, который должен отправлять ответы с кодами ответа HTTP (кодами состояния), такими как HTTP 200 OK или какой-то код 4XX или 5XX.
Как я могу сделать это в PHP?
У меня есть PHP-скрипт, который должен отправлять ответы с кодами ответа HTTP (кодами состояния), такими как HTTP 200 OK или какой-то код 4XX или 5XX.
Как я могу сделать это в PHP?
Я только что нашел этот вопрос и подумал, что на него нужен более исчерпывающий ответ:
Начиная с 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 strong >
Очевидно, что при использовании этого первого варианта есть несколько проблем. Самая большая из которых, как мне кажется, заключается в том, что он частично анализируется PHP или веб-сервером и плохо документирован.
Начиная с 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) найти что-нибудь вроде http_response_text () в мире 5.4? По крайней мере, старый header () может повлиять на текст после кода состояния.
- person Bob Stein; 19.08.2013
headers_sent()
верно, если вы не можете добавить больше заголовков, потому что контент уже был отправлен, а не если вы добавили заголовок. (2) К сожалению, нет. Однако другие языки имеют лучшую поддержку
- person dualed; 19.08.2013
header('none', false, $response);
, что приводит к желаемому коду ответа и без дополнительного заголовка.
- person Perry; 14.02.2014
http_response_code
(и, возможно, в более общем плане изменение заголовка) больше не работает после того, как вы что-то echo
. Надеюсь, это поможет.
- person Neptilo; 24.10.2014
header('Status: 301 Moved Permanently'); header("Location: $url", true, 301);
отправляет HTTP/1.1 301 Moved Permanently
и новое местоположение. Также работает для 404 (очевидно, без заголовка местоположения)
- person Josh; 15.11.2015
header('Status: 404 Not Found',true,404);
под PHP-FPM
- person Josh; 15.11.2015
http_response_code()
нельзя использовать для создания пользовательских кодов ошибок. Например, http_response_code(930)
приведет к тому, что файл журнала apache будет правильно отображать 930, но на самом деле клиенту будет отправлена ошибка 500. Вместо этого используйте метод header()
для этого, по общему признанию, странного варианта использования.
- person jlh; 31.08.2016
К сожалению, я обнаружил, что решения, представленные @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
Существует как минимум 2 случая, когда вызов http_response_code()
приводит к неожиданному поведению:
Для справки здесь приведен полный список кодов состояния ответа HTTP (этот список включает коды из интернет-стандартов IETF, а также других RFC IETF. Многие из них в настоящее время НЕ поддерживаются функцией PHP http_response_code): http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
Вы можете легко проверить эту ошибку, позвонив:
http_response_code(521);
Сервер отправит HTTP-код ответа «500 Internal Server Error», что приведет к неожиданным ошибкам, если, например, у вас есть пользовательское клиентское приложение, вызывающее ваш сервер и ожидающее некоторых дополнительных кодов HTTP.
Мое решение (для всех версий PHP, начиная с 4.1.0):
$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:
http://php.net/manual/en/function.http-response-code.php
Добавьте эту строку перед любым выводом тела, если вы не используете буферизацию вывода.
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
Проблема связана с отправкой заголовка Status: 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 не включает эту функцию:
<?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 через две разные среды:
В среде веб-сервера верните предыдущий код ответа, если вы предоставили код ответа или если вы не предоставили никакого кода ответа, тогда будет напечатано текущее значение. Значение по умолчанию - 200 (ОК).
В среде CLI будет возвращено true, если вы указали код ответа, и false, если вы не укажете response_code.
Пример среды веб-сервера для возвращаемого значения Response_code:
var_dump(http_respone_code(500)); // int(200)
var_dump(http_response_code()); // int(500)
Пример среды CLI для возвращаемого значения Response_code:
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); не работает, потому что тестовое предупреждение 404 https://developers.google.com/speed/pagespeed/insights/