PHP: Cannot modify header information — headers already sent

  • Обновлено
  • Чтение ≈ 4 минуты

Краткий ответ

«Cannot modify header information — headers already sent» в PHP возникает, когда вывод начался раньше вызова header(), setcookie() или session_start(). Найдите место вывода в сообщении (output started at), уберите пробелы, BOM и лишний echo.

В этой статье
  1. Что означает ошибка
  2. Причины и решения
  3. Пошаговое решение

#Что означает ошибка

Сообщение
headers already sent

HTTP-заголовки (в том числе cookie и редиректы) отправляются перед телом ответа. Как только PHP отправил первый байт содержимого, изменять заголовки поздно. Сообщение обычно содержит подсказку: (output started at /var/www/site/config.php:3) — файл и строка, где вывод начался. Начинайте именно с неё.

#Причины и решения

Возможная причинаКак узнатьЧто делать
Пробелы или перевод строки до <?phpВ начале файла есть пустая строка или пробел.output started at ... :1.Удалите всё перед <?php.
BOM в файлеРедактор сохранил UTF-8 с BOM, и перед кодом выводятся три байта.В журнале :1, пробелов не видно.Сохраните UTF-8 без BOM.
echo, print или HTML до headerВывод идёт раньше вызова header().Строка с echo перед редиректом.Переместите header() выше или используйте буфер.
Закрывающий ?> с пробелом послеПосле ?> в include-файле остался перевод строки.Ошибка указывает на последнюю строку include.Уберите ?> в конце файлов с кодом.

#Пошаговое решение

  1. Прочитайте сообщение целикомСкопируйте текст предупреждения целиком: важна часть output started at /путь/файл.php:строка. Первый указанный файл и строка — место, где PHP начал вывод; путь к header() или setcookie() обычно указывается позже. На копии проекта откройте первый файл в редакторе, перейдите к строке и посмотрите не только на echo, но и на HTML, пробелы, включённые шаблоны и сообщения об ошибках. Проблема не в недоступности сайта, а в том, что HTTP-заголовки уже были отправлены клиенту.
  2. Откройте файл из «output started at»Если предупреждение указывает на начало PHP-файла, откройте его в VS Code и проверьте самый первый символ: в чистом PHP-файле до <?php не должно быть HTML, пробела или перевода строки. В файле-шаблоне HTML до PHP может быть намеренным — тогда переместите установку заголовков раньше, а не удаляйте верстку. Убедитесь, что файл сохранён в UTF-8 без BOM. После изменения повторите запрос и проверьте, что предупреждение исчезло и страница работает корректно.
  3. Проверьте BOMДля проверки BOM откройте в VS Code проблемный PHP-файл, нажмите по надписи кодировки в строке состояния и выберите «Сохранить с кодировкой → UTF-8». Перед сохранением убедитесь, что это именно UTF-8 без BOM, и сохраните резервную копию, если на сайте старые файлы используют Windows-1251. В Linux можно проверить первые три байта командой head -c 3 index.php | xxd: последовательность ef bb bf указывает на BOM, но не доказывает, что именно этот файл виновен. Не перекодируйте весь сайт автоматически.
  4. Уберите закрывающий ?>В файле, содержащем только PHP-код, найдите закрывающий ?> в конце и удалите его, если после него выводятся случайные пробелы или пустые строки. Не удаляйте обязательный закрывающий тег в шаблонах, где далее расположен HTML. Изменение проверьте на копии и откройте соответствующую страницу. Если HTML уже выведен до выполнения кода, удаление ?> ничего не исправит: переходите к корректировке порядка обработки запроса.
  5. Переместите вызов headerНайдите вызовы header(), setcookie() и session_start() с помощью поиска по проекту в редакторе. Перенесите их в обработчик запроса до первого вывода (echo, печати шаблона или HTML), сохраняя зависимость от проверок авторизации. После header('Location: ...') обычно нужен exit;, чтобы код не продолжал формировать страницу. Проверьте в инструментах разработчика браузера вкладку Network → конкретный запрос → Response Headers: код ответа, Location и Set-Cookie должны соответствовать ожидаемому поведению.
  6. Используйте буферизациюЕсли архитектуру приложения быстро изменить нельзя, буферизация ob_start() до вывода может временно отложить отправку заголовков, но это не исправляет ошибочную последовательность действий. Сначала проверьте, не запускает ли фреймворк собственную буферизацию, и не делает ли код flush()/ob_end_flush() раньше времени. Менять output_buffering на всём сервере ради одной страницы не стоит. Сделайте изменение в испытательной среде, затем проверьте редиректы и сеансы; если сбой остаётся, вернитесь к порядку формирования ответа.
  7. Включите показ ошибок на время отладкиДля диагностики на рабочем сайте не включайте display_errors=1: появляющиеся предупреждения могут отправить вывод и усугубить проблему, а посетители увидят внутренние пути. Настройте запись ошибок в защищённый журнал средствами панели управления PHP, затем воспроизведите запрос и сравните время со строками журнала. На испытательном экземпляре можно включить подробные сообщения, но не публиковать их наружу. После исправления проверьте вход пользователя, отправку cookie и переадресацию; если заголовки отсутствуют, соберите путь и строку первого вывода для разработчика.
  8. Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
    Выберите подходящий вариант — это не команды для последовательного выполнения
    Вариант 1Проверяйте именно файл из «output started at».
    Linux · Терминал (Bash)Команда
    Проверяйте именно файл из «output started at». Команда только читает байты, не меняет файл; для других кодировок анализ нужен отдельно.
    # Только Linux/macOS, проверка указанного в предупреждении PHP-файла:
    head -c 3 index.php | xxd
    # Ожидаемое начало UTF-8 без BOM: 3c 3f 70 (<?p)
    Вариант 2Правильный порядок: заголовок до любого вывода.
    redirect.php
    Правильный порядок: заголовок до любого вывода.
    <?php
    ob_start();
    session_start();
    if (!isset($_SESSION['user'])) {
        header('Location: /login/');
        exit;
    }
    echo 'Страница для авторизованных';

В WordPress ошибка чаще всего вызвана пробелом в конце wp-config.php или functions.php темы, либо плагином, который выводит текст при активации. Отключите плагины переименованием папки wp-content/plugins и проверьте. После исправления не забудьте выключить вывод ошибок на рабочем сайте: display_errors = Off. Подробности — руководство PHP по header().

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 1 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.