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

Раздел: PHP -> Обработка ошибок

Обработка HTTP кодов ответа в PHP

Корректная установка кодов состояния HTTP играет важную роль для SEO, работы API, обработки ошибок и пользовательского опыта. В PHP существует несколько способов задать код ответа, каждый из которых имеет свои особенности и области применения.

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

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

Как задать код 404 с помощью http_response_code?

<?php
http_response_code(404);
?>

Php not found (ошибка 404 в php)

В этом примере функция устанавливает код 404 (Not Found). При этом заголовок отправляется автоматически, если вывод ещё не начался. Функция также может быть вызвана без аргументов для получения текущего кода.

Типичные проблемы:

  • Если до вызова http_response_code() уже был отправлен какой-либо вывод (echo, пробелы), заголовок не установится. Решение - убедиться, что скрипт не производит вывод до вызова, либо использовать буферизацию (ob_start()).
  • В некоторых окружениях (например, FastCGI) http_response_code() может не сработать, если ранее был отправлен нестандартный заголовок. В таких случаях помогает комбинация с header().

Вариант 1: Установка кода через header()

Как задать код 403 с помощью header?

<?php
header('HTTP/1.1 403 Forbidden');
?>

Php try (обработка исключений try-catch в php)

Этот способ работает во всех версиях PHP и даёт полный контроль над строкой статуса. Рекомендуется явно указывать протокол (HTTP/1.1).

Проблема: если используется http_response_code() после header(), код может перезаписаться. Лучше выбрать один метод.

Вариант 2: Получение текущего кода ответа

Как узнать, какой статус был установлен?

<?php
http_response_code(404);
$code = http_response_code();
echo $code; // 404
?>

Php код ответа (код ответа http в php)

Для старых версий PHP (до 5.4) можно использовать функцию headers_list():

<?php
header('HTTP/1.1 404 Not Found');
$headers = headers_list();
echo $headers[0]; // HTTP/1.1 404 Not Found
?>

Post 500 php (ошибка 500 при post-запросе в php)

Функция headers_list() возвращает все отправленные заголовки; для извлечения кода требуется парсинг строки.

Вариант 3: Редирект с кодом 301 или 302

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

<?php
header('Location: /new-page', true, 301);
exit;
?>

Php страница не найдена (страница 404 в php)

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

Если после header() не вызвать exit, может быть отправлен дополнительный контент, что приведёт к ошибке или нежелательному поведению.

Вариант 4: Отправка JSON с кодом для API

Как вернуть статус 422 и сообщение в формате JSON?

<?php
http_response_code(422);
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['error' => 'Invalid input'], JSON_UNESCAPED_UNICODE);
exit;
?>

Access denied php (ошибка доступа в php)

Этот подход часто используется в REST API. Код состояния устанавливается до вывода JSON.

Ошибка: если не указать заголовок Content-Type, клиент может не распознать ответ как JSON. Также следует избегать вывода до установки кода.

Вариант 5: Пользовательская страница ошибки 404

Как отобразить кастомную страницу при отсутствии ресурса?

<?php
if (!$pageFound) {
    http_response_code(404);
    include '404.php';
    exit;
}
?>

Pdo php try (pdo php try)

Подключается отдельный файл с HTML-разметкой ошибки. Важно, чтобы в файле не было лишнего вывода до установки кода.

Браузеры могут кэшировать страницу 404 - добавляйте заголовки Cache-Control: no-cache для статических ошибок.

Вариант 6: Обработка исключений с кодом 500

Как отправить статус 500 при возникновении исключения?

<?php
try {
    // опасный код
} catch (Exception $e) {
    http_response_code(500);
    echo 'Внутренняя ошибка сервера';
    // логирование $e->getMessage()
}
?>

Php include try (php include с try)

В production режиме не рекомендуется выводить текст исключения.

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

Вариант 7: Установка кода без http_response_code (PHP < 5.4)

Как задать статус в старых версиях PHP?

<?php
header('HTTP/1.1 403 Forbidden');
?>

Если требуется поддержка очень старых систем, можно использовать функцию header() с полной строкой статуса. Однако современное окружение обычно включает PHP 5.4+.

Протокол (HTTP/1.0 или HTTP/1.1) должен соответствовать возможностям сервера. В большинстве случаев подходит HTTP/1.1.

- Warning php page (предупреждение php)
- Reporting php (настройка отображения ошибок php)
- Php error log (лог ошибок php)

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

Ниже приведены развёрнутые примеры с пояснениями, демонстрирующие различные сценарии применения HTTP кодов в PHP.

1. Отправка разных кодов в зависимости от логики

Пример обработки REST запроса с возвратом кодов 200, 201, 204, 400, 401, 404, 409, 422, 500.

Пример
<?php
// Симуляция запроса
$method = $_SERVER['REQUEST_METHOD'];
$resource = $_GET['resource'] ?? null;

if ($method === 'POST' && $resource === 'users') {
    // Успешное создание
    http_response_code(201);
    header('Content-Type: application/json');
    echo json_encode(['id' => 42, 'message' => 'Created']);
} elseif ($method === 'GET' && $resource === 'users') {
    // Успешный запрос
    http_response_code(200);
    echo json_encode(['users' => []]);
} elseif ($method === 'DELETE' && $resource === 'users') {
    // Нет содержимого
    http_response_code(204);
    exit;
} elseif ($method === 'GET' && !$resource) {
    // Неверный запрос
    http_response_code(400);
    echo json_encode(['error' => 'Resource parameter missing']);
} else {
    // Не найден
    http_response_code(404);
    echo json_encode(['error' => 'Not found']);
}
?>
Результат: заголовки ответа с соответствующими кодами и JSON телом.

2. Обработка авторизации с кодом 401

Пример
<?php
session_start();
if (!isset($_SESSION['user'])) {
    http_response_code(401);
    header('WWW-Authenticate: Bearer realm="API"');
    echo json_encode(['error' => 'Unauthorized']);
    exit;
}
// остальной код
?>
Клиент получит 401 и заголовок WWW-Authenticate, указывающий на необходимость авторизации.

3. Буферизация вывода для установки кода после частичного вывода

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

Пример
<?php
ob_start();
echo 'Неполный вывод';

if (some_error()) {
    ob_clean(); // очищаем буфер
    http_response_code(500);
    echo 'Ошибка';
}
ob_end_flush();
?>
Если ошибки нет, будет выведен "Неполный вывод". При ошибке буфер очищается и отправляется код 500.

4. Логирование кодов ответа с деталями

Пример
<?php
function respondAndLog($code, $message, $data = []) {
    http_response_code($code);
    header('Content-Type: application/json');
    $response = ['code' => $code, 'message' => $message];
    if ($data) {
        $response['data'] = $data;
    }
    echo json_encode($response, JSON_UNESCAPED_UNICODE);
    
    file_put_contents('/var/log/http_codes.log', date('Y-m-d H:i:s') . " $code $message\n", FILE_APPEND);
    exit;
}

// Использование
respondAndLog(422, 'Validation failed', ['errors' => ['email' => 'Invalid format']]);
?>
Файл лога получит строку с временем, кодом и сообщением.

5. Комбинирование с try-catch и кастомным обработчиком ошибок

Пример
<?php
set_exception_handler(function ($exception) {
    http_response_code(500);
    header('Content-Type: application/json');
    echo json_encode(['error' => 'Internal Server Error']);
    file_put_contents('/var/log/exceptions.log', $exception->getMessage() . "\n", FILE_APPEND);
    exit;
});

// Здесь может быть код, выбрасывающий исключение
throw new Exception('Что-то пошло не так');
?>
Все необработанные исключения приведут к ответу 500 с JSON.

6. Использование header_remove() для сброса кода

Пример
<?php
http_response_code(200);
header('X-Custom: value');
// Позже решаем изменить код
header_remove('X-Custom');
http_response_code(403);
?>
Удаляется ранее установленный заголовок X-Custom, код заменяется на 403.

7. Работа с FastCGI: альтернативный способ

Пример
<?php
if (function_exists('fastcgi_finish_request')) {
    http_response_code(200);
    echo 'OK';
    fastcgi_finish_request();
    // длительная операция после отправки ответа
}
?>
После fastcgi_finish_request() можно выполнять длительные задачи, не блокируя клиента.

Все примеры требуют, чтобы до установки кода не было вывода (кроме случаев с буферизацией). Соблюдение этого правила гарантирует корректную работу HTTP кодов в PHP.

Код ответа HTTP в PHP - comments

En
Php код ответа (php)