У мене є сценарій 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
Очевидно, що існує декілька проблем при використанні першого варіанту. Найбільший з яких я думаю, це те, що він частково проаналізований 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(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? Принаймні старий заголовок () може впливати на текст після коду статусу.
headers_sent()
вірно, якщо ви не можете додати більше заголовків, оскільки вміст уже надіслано, а не якщо ви додали заголовок. (2) Вибачте, ні. Інші мови мають кращу підтримку
http_response_code
(і, можливо, більш загальна зміна заголовка) більше не працює після того, як ви echo
щось зробите . Сподіваюся, це допомагає.
На жаль, я знайшов рішення, представлені @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: //uk.wikipedia .org / wiki / List_of_HTTP_status_codes
Ви можете легко протестувати цю помилку, зателефонувавши:
http_response_code(521);
Сервер надішле HTTP-код "500 внутрішніх помилок сервера", що призведе до несподіваних помилок, якщо у вас є, наприклад, спеціальна клієнтська програма, яка дзвонить на ваш сервер і очікує отримання додаткових кодів 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:
Додайте цей рядок перед будь-яким виходом тіла, якщо ви не використовуєте буферизацію виводу.
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");
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/
Якщо ваша версія 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 Environment істинним буде повернення, якщо ви вказали код відповіді, а false - якщо ви не вказали код відповіді.
Приклад середовища повернення веб-сервера коду 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('X-PHP-Response-Code: 404', true, 404);
працює правильно в PHP-FPM (FastCGI)