Ошибка Cannot modify header information после include шаблона

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

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

Исправлять нужно точку первого вывода, указанную в сообщении «output started at», а не убирать сам заголовок. Особенно часто проблема появляется после вставки HTML-макета или сохранения шаблона с маркером BOM.

В этой статье
  1. Симптомы, область применения и причины
  2. Безопасная диагностика и пошаговое исправление
  3. Как проверить результат и что делать дальше

#Симптомы, область применения и причины

После подключения шаблона PHP не может отправить cookie, перенаправление или другой HTTP-заголовок. Как найти ранний вывод, пробелы и BOM до вызова header()/setcookie()/session_start(). Исправлять нужно точку первого вывода, указанную в сообщении «output started at», а не убирать сам заголовок. Особенно часто проблема появляется после вставки HTML-макета или сохранения шаблона с маркером BOM.

Возможная причинаКак узнатьЧто делать
HTML или echo выполнен до заголовковШаблон сразу выводит разметку, а контроллер позже вызывает header или session_start.Ошибка возникает после включения конкретного шаблона; «output started at» указывает на него.Переместить формирование заголовков до любого вывода.
BOM или пробелы в PHP-файлеНевидимые байты до <?php или после ?> становятся телом ответа.В предупреждении указана первая строка шаблона; визуально вывод отсутствует.Сохранить чистый UTF-8 без BOM и убрать ненужный закрывающий PHP-тег.
Предупреждение PHP вывелось в ответ раньшеУведомление об ошибке само стало текстом, отправленным до header.До основной ошибки браузер показывает Warning/Notice.Исправить исходное предупреждение; не полагаться на подавление вывода.

#Безопасная диагностика и пошаговое исправление

  1. Сохраните полную строку ошибкиВ тестовом окружении воспроизведите действие: вход в систему, перенаправление после формы или установку cookie. Откройте журнал PHP в панели сайта. Запишите оба пути и строки из headers already sent by (output started at ...:строка) in ... on line .... Первое местоположение указывает, где начался ответ, второе — где пытались отправить заголовок. Не включайте отображение предупреждений на общедоступном сайте.
  1. Проверьте порядок выполнения в контроллереОткройте указанный PHP-файл в редакторе кода (например, VS Code или редакторе панели). Найдите include, require, echo, выход из режима ?>, HTML-разметку и вызов header, setcookie или session_start. Выводимый шаблон должен запускаться после проверки прав, обработки формы и установки заголовков. Не изменяйте рабочий сайт напрямую: сделайте копию контроллера и проверьте изменения в тестовом окружении.
  1. Найдите невидимые байты в начале файлаОткройте шаблон, который назван после output started at, в редакторе с отображением кодировки. В VS Code в нижней строке состояния нажмите на обозначение кодировки; при необходимости выберите «Сохранить с кодировкой» → «UTF-8» без BOM. Проверьте, чтобы до <?php не было пустых строк или пробелов; для файла с одним PHP-кодом предпочтительно не писать закрывающий тег ?>. Если BOM нужен по специфике стороннего файла, согласуйте преобразование с разработчиком.
  1. Проверьте, отправлялись ли заголовки раньшеВставьте временную проверку headers_sent($file, $line) непосредственно перед проблемным вызовом заголовка и записывайте значения в закрытый журнал. Если функция возвращает true, первые байты уже отправлены; откройте именно указанный файл и строку. Если false, проверьте другие ветви выполнения или буферизацию: сообщение могло относиться к иному запросу. После диагностики код обязательно удалите.
  2. Пример кода по теме
    PHP
    Вставлять непосредственно перед header()/setcookie() в тестовой среде; выводятся сведения только в закрытый журнал.
    <?php
    if (headers_sent($file, $line)) {
        error_log('HTTP output started: '.$file.':'.$line);
    }
  1. Перенесите перенаправление перед шаблономВ обработчике после проверки данных формы выполните header("Location: /account/") и сразу exit, прежде чем подключить визуальный шаблон или сделать echo. Адрес /account/ — лишь пример внутреннего маршрута: используйте реально существующую страницу вашего приложения. Если после этого пользователь видит пустую страницу, сначала проверьте журнал — exit сознательно останавливает рендеринг после редиректа.
  2. Пример кода по теме
    PHP
    Код показывает порядок действий, но не готовый контроллер: авторизация и адрес маршрута должны быть реализованы в вашем приложении.
    <?php
    // После успешной авторизации, ДО подключения шаблона:
    header('Location: /account/', true, 303);
    exit;
  1. Не маскируйте ошибку буферизациейob_start() может временно отсрочить передачу содержимого, но не гарантирует верный порядок вывода и заголовков. Применяйте буферизацию только если так устроен проект и вы понимаете сброс буферов. Не используйте @header() и глобальное подавление ошибок как исправление: браузер всё равно может получать неправильный ответ.
  1. Проверьте синтаксис и конечные HTTP-заголовкиВ терминале разработчика выполните php -l с точным путём копии изменённого PHP-файла, предварительно указав правильное имя после команды, либо используйте синтаксическую проверку редактора. Затем запустите исходное действие в браузере и во вкладке «Сеть» проверьте статус ответа и Location/Set-Cookie. Если переделка нарушила работу, восстановите сохранённый контроллер и шаблон, сравните строки и повторите отладку.

#Как проверить результат и что делать дальше

Работа исправлена, когда на исходном действии нет предупреждения headers already sent, а браузер получает нужный статус, Location или Set-Cookie. Если ошибка осталась, найдите другую точку вывода через headers_sent() и восстановите файлы из копий при неуспешном изменении.

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

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

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