HTTP статус коды в PHP: как правильно установить и почему это важно

Раздел: Веб-разработка -> HTTP и заголовки

Управление HTTP статус кодами в PHP

HTTP статус код (response code) является неотъемлемой частью ответа сервера. Он сообщает клиенту об успешности или проблемах обработки запроса. В PHP существует несколько способов установки этого кода. Рассмотрим наиболее эффективный и часто используемый метод, а также альтернативные подходы.

Основное решение: функция http_response_code()

Начиная с PHP 5.4.0, доступна встроенная функция http_response_code(). Она предназначена как для получения текущего кода, так и для его установки. Для установки достаточно передать целочисленный код в качестве аргумента:

<?php
http_response_code(404);

Http response code php (установка http статус кода в php)

После этого PHP автоматически установит соответствующий заголовок, например: HTTP/1.1 404 Not Found. Функция работает прозрачно независимо от режима исполнения (CGI, FastCGI, модуль Apache) и не требует ручной установки заголовка с помощью header().

Если нужно просто получить текущий код без изменения, вызывайте ее без параметров:

<?php
$code = http_response_code();
echo $code; // выведет, например, 200

Code php header (установка http заголовков в php)

Возможные проблемы и ошибки:

  • В версиях PHP ниже 5.4.0 функция отсутствует. Решение: использовать header() и константу протокола.
  • Если до вызова http_response_code() уже был отправлен какой-либо вывод (например, пробелы перед <?php), функция выдаст предупреждение и не сработает. Решение: контролировать буферизацию, либо явно начинать буферизацию вывода.
  • Некоторые кэширующие прокси или фронтенд-серверы (nginx) могут игнорировать код, если он установлен неправильно. Рекомендуется всегда устанавливать код до вывода тела ответа.

Как установить статус код с помощью header()?

До появления http_response_code() основным методом была функция header(). Она требует явного указания протокола и текстовой причины (reason phrase). Например, код 404:

<?php
header("HTTP/1.0 404 Not Found");
// или
header("HTTP/1.1 404 Not Found");

Важно указать корректную версию протокола (обычно 1.1). Если протокол не указан, PHP попытается определить его самостоятельно, но это может привести к неожиданному поведению.

Типичная ошибка:

После header() может быть автоматически добавлен код статуса 200, если не вызвать exit() или не убедиться, что дальнейший скрипт не изменит его. Также при использовании header() для редиректа (302) нужно отдельно передавать код.

Как установить код вместе с пользовательскими заголовками?

Иногда требуется одновременно задать код статуса и добавить кастомные заголовки. Удобно комбинировать http_response_code() и header():

<?php
http_response_code(201);
header("Location: /new/resource");
header("X-Custom: value");

При этом код 201 (Created) и заголовок Location будут отправлены корректно. Однако следует помнить, что код статуса должен быть совместим с заголовком (например, для перенаправлений используется 301 или 302).

Проблема с буферизацией вывода:

Если вывод уже начат (был отправлен контент), установка заголовков становится невозможной. В таких случаях проверьте настройку output_buffering в php.ini или используйте ob_start(). Функция http_response_code() также не сработает после вывода, так как заголовки уже отправлены.

Как использовать константы для удобства?

Для улучшения читаемости кода можно определить константы с кодами статуса. Хотя PHP не предоставляет их из коробки, разработчики часто создают собственные или подключают библиотеки, например, из фреймворков (Symfony, Laravel).

<?php
define('HTTP_OK', 200);
define('HTTP_NOT_FOUND', 404);
define('HTTP_INTERNAL_SERVER_ERROR', 500);

http_response_code(HTTP_NOT_FOUND);

Это позволяет избежать магических чисел и делает код самодокументируемым. В PHP 8 дополнительных встроенных констант для всех кодов не появилось, но можно использовать сторонние пакеты через Composer.

При выборе констант важно не создавать конфликты имен. Рекомендуется придерживаться единого префикса, например, HTTP_.

Как установить код для разных версий HTTP и FastCGI?

В средах с FastCGI (например, Nginx + PHP-FPM) функция http_response_code() работает корректно, так как PHP сам обрабатывает заголовки. Однако если вы используете header() вручную, то протокол может быть интерпретирован как CGI. В этом случае вместо строки 'HTTP/1.1 ...' можно использовать Status::

<?php
header("Status: 404 Not Found");

Этот способ устарел, но до сих пор встречается в старых системах. Настоятельно рекомендуется переходить на http_response_code().

Опасность некорректного протокола:

Если указан неподдерживаемый протокол (например, HTTP/2.0), сервер может проигнорировать заголовок или ответить с ошибкой. Всегда используйте HTTP/1.1 или HTTP/1.0.

Расширенные примеры установки HTTP статус кодов в PHP

Ниже приведены подробные примеры с кодом и результатами работы.

Пример 1: Установка различных кодов с помощью http_response_code()

Пример
<?php
// Успешный ответ
http_response_code(200);
echo "OK";
?>

Результат (заголовки ответа):

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
...
Пример
<?php
// Ресурс создан
http_response_code(201);
echo "Created";
?>
HTTP/1.1 201 Created
...
Пример
<?php
// Перенаправление на другой URL (рендер страницы обычно не нужен)
http_response_code(301);
header("Location: /new-page");
exit;
?>
HTTP/1.1 301 Moved Permanently
Location: /new-page
...
Пример
<?php
// Ошибка сервера 500
http_response_code(500);
echo "Internal Server Error";
?>
HTTP/1.1 500 Internal Server Error
...

Пример 2: Динамическое определение кода в зависимости от логики

Пример
<?php
$data = fetchData();
if (!$data) {
    http_response_code(404);
    echo "Resource not found";
} elseif ($data['status'] === 'expired') {
    http_response_code(410); // Gone
    echo "Resource is gone";
} else {
    http_response_code(200);
    echo json_encode($data);
}
?>

В данном примере код меняется в соответствии с состоянием данных. Важно, что установка кода происходит до вывода любого контента.

Пример 3: Установка кода при использовании AJAX или API

Пример
<?php
header("Content-Type: application/json");

$input = json_decode(file_get_contents('php://input'), true);
if (empty($input['action'])) {
    http_response_code(400);
    echo json_encode(['error' => 'Missing action']);
    exit;
}
// обработка...
http_response_code(200);
echo json_encode(['result' => 'success']);
?>

Клиент получит код 400 при неверном запросе, что позволяет корректно обрабатывать ошибки на стороне фронтенда.

Пример 4: Отображение пользовательского тела ошибки вместе с кодом

Пример
<?php
http_response_code(404);
?>
<!DOCTYPE html>
<html>
<head><title>Страница не найдена</title></head>
<body>
<h1>404 - Ошибка</h1>
<p>Запрашиваемая страница не существует.</p>
</body>
</html>

Результат: браузер получает заголовок 404, а содержимым идет HTML-страница. Это важно для SEO, чтобы поисковики не индексировали несуществующие страницы как 200.

Пример 5: Проверка текущего кода до и после установки

Пример
<?php
// начальный код обычно 200
echo "До: " . http_response_code() . "\n"; // 200

http_response_code(403);
echo "После: " . http_response_code() . "\n"; // 403
?>

Этот прием полезен для отладки: можно проверить, не был ли код изменен каким-либо функциональным блоком.

Пример 6: Использование header() с явным протоколом (для старых версий PHP)

Пример
<?php
// Только для PHP < 5.4
header("HTTP/1.1 200 OK");
// или
header("HTTP/1.0 200 OK");
echo "Content";
?>

Проблема: если не указать протокол, PHP может использовать значение по умолчанию, что иногда приводит к "HTTP/1.0 200 OK" для FastCGI. Лучше использовать http_response_code().

Пример 7: Комбинация с заголовками кэширования

Пример
<?php
http_response_code(200);
header("Cache-Control: max-age=3600, public");
header("Expires: " . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
echo "Этот контент может кэшироваться час";
?>

Код 200 гарантирует, что кэш будет воспринят положительно. В случае ошибок (4xx/5xx) заголовки кэширования обычно не применяются.

Установка HTTP статус кода в PHP - comments

En
Http response code php (php)