PHP: Как отправить код ответа HTTP?

У меня есть PHP script, который должен делать ответы с кодами ответа HTTP (статусные коды), такими как HTTP 200 OK, или с кодом 4XX или 5XX.

Как я могу сделать это в PHP?

Ответ 1

Я только что нашел этот вопрос и подумал, что ему нужен более полный ответ:

Как и в PHP 5.4, для этого можно использовать три метода:

Сборка кода ответа по своему усмотрению (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_sapi_name() требует PHP 4.0.1

Третий аргумент функции заголовка (PHP >= 4.3)

Очевидно, что есть несколько проблем при использовании этого первого варианта. Самым большим из которых я считаю, что он частично анализируется 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() была представлена ​​в 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;
    }
}

Ответ 2

К сожалению, я нашел решения, представленные @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() возникает не менее 2 случаев:

    • Когда PHP сталкивается с кодом ответа HTTP, он не понимает, PHP заменит код на тот, который он знает из той же группы. Например, "521 веб-сервер выключен" заменяется "500 Internal Server Error". Многие другие необычные коды ответов от других групп 2xx, 3xx, 4xx обрабатываются таким образом.
    • На сервере с функциями php-fpm и nginx http_response_code() МОЖЕТ изменить код, как ожидалось, но не на сообщение. Это может привести к появлению, например, странного заголовка "404 OK". Эта проблема также упоминается на веб-сайте PHP по комментарию пользователя http://www.php.net/manual/en/function.http-response-code.php#112423

Для справки здесь приведен полный список кодов статуса ответа 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. Текущий протокол должен быть обнаружен.

Любые тесты и комментарии оценены.

Ответ 3

начиная с 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

Ответ 4

Добавьте эту строку перед любым выходом тела, если вы не используете буферизацию вывода.

header("HTTP/1.1 200 OK");

Замените часть сообщения ( "ОК" ) соответствующим сообщением и кодом состояния с кодом (404, 501 и т.д.)

Ответ 5

Если вы здесь, потому что 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");

Ответ 6

С помощью функции header. В этом разделе приведен пример использования первого параметра.

Ответ 8

Мы можем получить другое возвращаемое значение из http_response_code через две разные среды:

  1. Среда веб-сервера
  2. Среда CLI

В среде веб-сервера верните предыдущий код ответа, если вы указали код ответа или если вы не указали код ответа, тогда будет напечатано текущее значение. Значение по умолчанию - 200 (ОК).

В среде CLI будет возвращаться значение true, если вы указали код ответа, и значение false, если вы не указали код ответа.

Пример среды веб-сервера возвращаемого значения кода ответа:

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)