PHP: Как отправить код ответа HTTP? - PullRequest
217 голосов
/ 15 июля 2010

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

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

Ответы [ 8 ]

414 голосов
/ 18 августа 2012

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

Начиная с PHP 5.4 есть три способа сделать это:

Сборка ответасобственный код (PHP> = 4.0)

Функция header() имеет специальный вариант использования, который обнаруживает строку ответа HTTP и позволяет заменить ее на пользовательскую

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 или веб-сервером и плохо документирован.

Начиная с версии 4.3, у функции header есть 3-й аргумент, который позволяет вам несколько удобно устанавливать код ответано использование этого требует, чтобы первый аргумент был непустой строкой.Вот два варианта:

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

Я рекомендую второй .Первый работает во всех протестированных мною браузерах, но у некоторых второстепенных браузеров или веб-сканеров может возникнуть проблема со строкой заголовка, которая содержит только двоеточие.Название поля заголовка во 2-м.вариант, конечно, никак не стандартизирован и может быть изменен, я просто выбрал, надеюсь, описательное имя.

функция http_response_code (PHP> = 5.4)

http_response_code()*Функция 1055 * была введена в 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;
    }
}
36 голосов
/ 21 апреля 2014

К сожалению, я обнаружил, что решения, представленные @dualed, имеют различные недостатки.

  1. Использование substr($sapi_type, 0, 3) == 'cgi' не достаточно для быстрого обнаружения CGI.При использовании PHP-FPM FastCGI Process Manager, php_sapi_name() возвращает fpm, а не cgi

  2. Fasctcgi и php-fpm выявляют еще одну ошибку, упомянутую @Josh - использование 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'] (доступно начиная с PHP 4.1.0

  4. Существует как минимум 2 случая, когда вызов http_response_code() приводит к неожиданному поведению:

    • Когда 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.Текущий протокол должен быть обнаружен.

Любые тесты и комментарии приветствуются.

14 голосов
/ 06 января 2017

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

8 голосов
/ 15 июля 2010

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

header("HTTP/1.1 200 OK");

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

7 голосов
/ 13 августа 2013

Если вы находитесь здесь из-за того, что 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 голосов
/ 15 июля 2010

С функцией header . В разделе приведен пример первого принятого параметра.

2 голосов
/ 07 апреля 2016
header("HTTP/1.1 200 OK");
http_response_code(201);

http_response_code (200); не работает, потому что тестовое предупреждение 404 https://developers.google.com/speed/pagespeed/insights/

1 голос
/ 17 марта 2019

Мы можем получить различное возвращаемое значение из 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)
...