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

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

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

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

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

    3-й аргумент функции заголовка (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; } } 

    К сожалению, я нашел решения, представленные @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 / вики / 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. Текущий протокол должен быть обнаружен.

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

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

     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 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"); http_response_code(201); 

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