Вопрос

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

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

Это было полезно?

Решение

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

Как и 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-й вариант.Первый делает работает во всех браузерах, которые я тестировал, но у некоторых второстепенных браузеров или веб-сканеров может возникнуть проблема со строкой заголовка, содержащей только двоеточие.Имя поля заголовка во 2-м.вариант, конечно, никоим образом не стандартизирован и может быть изменен, я просто выбрал, надеюсь, описательное название.

функция 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;
    }
}

Другие советы

К сожалению, я обнаружил, что решения, представленные @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 Внутренняя ошибка сервера".Многие другие необычные коды ответов из других групп 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.Должен быть обнаружен текущий протокол.

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

С 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

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

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 не нашел заголовок.Вы должны переопределить это. Это также будет работать:

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;
    }
.

We can get different return value from http_response_code via the two different environment:

  1. Web Server Environment
  2. CLI environment

At the web server environment, return previous response code if you provided a response code or when you do not provide any response code then it will be print the current value. Default value is 200 (OK).

At CLI Environment, true will be return if you provided a response code and false if you do not provide any response_code.

Example of Web Server Environment of Response_code's return value:

var_dump(http_respone_code(500)); // int(200)
var_dump(http_response_code()); // int(500)

Example of CLI Environment of Response_code's return value:

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); not work because test alert 404 https://developers.google.com/speed/pagespeed/insights/

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top