#Когда возникает ошибка
Ошибка Cannot modify header information - headers already sent by ... возникает, когда PHP пытается добавить HTTP-заголовок после начала вывода. Если подключённый PHP-файл сохранён как UTF-8 с BOM, три байта EF BB BF до открывающего <?php могут попасть в тело ответа ещё до header() или session_start(). Но причина бывает и в echo или пробелах; BOM надо подтвердить, а не удалять вслепую.
#Причины и признаки
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| UTF-8 BOM перед <?phpРедактор добавил три байта маркера в начале подключённого PHP-файла. | Журнал указывает на этот файл и строку 1; в шестнадцатеричном просмотре первые байты EF BB BF. | Сохраните PHP-файл как UTF-8 без BOM. |
| Пробелы или HTML вне PHPДо вызова header или session_start уже выведен текст. | Виновный файл начинается с HTML, пробела или содержит закрывающий ?> и следующий перевод строки. | Уберите непреднамеренный вывод в шаблоне и поднимите работу с заголовками раньше. |
| Заголовки уже отправлены другим компонентомВывод сделан до подключения файла, PHP только фиксирует место начала. | В сообщении указан другой файл/строка, чем предполагаемый конфиг. | Проверьте фактическое место, где начался вывод. |
#Пошаговая диагностика и устранение
- Уточните оба файла из сообщенияВ закрытом журнале найдите строку
headers already sent by (путь:строка)и место, где вызвалиheader()/session_start(). Откройте оба файла. Если сообщение указывает на строку 1 подключённого файла, это характерно для BOM, но не доказательство: сначала посмотрите начало файла и наличие случайного вывода. - Сохраните резервную копию перед изменениемСкопируйте проблемный PHP-файл и зафиксируйте его текущую кодировку. В редакторе Visual Studio Code откройте «Файл» → «Открыть файл» и выберите именно файл, указанный в журнале. Если работаете по SSH, скопируйте файл в закрытую служебную папку или воспользуйтесь управлением версиями. Не меняйте все PHP-файлы пакетно.
- Проверьте начальные байты файлаВ терминале Linux выполните
xxd -l 8 путь/к/файлу.phpпри наличии xxd или откройте файл шестнадцатеричным просмотрщиком в редакторе. Если вывод начинаетсяef bb bf 3c 3f 70 68 70, это BOM перед<?php. Если начинается сразу3c 3f 70 68 70, BOM там нет — ищите пробелы, HTML или преждевременный вывод в другом файле. - Сохраните файл как UTF-8 без BOMВ Visual Studio Code нажмите обозначение кодировки справа в строке состояния → «Сохранить с кодировкой» → «UTF-8» (не «UTF-8 with BOM»). Проверьте, что текст на русском сохранился без искажений. Внимание: если исходный файл был в Windows-1251, сначала определите действительную кодировку — обычная смена метки сохранения без корректного чтения испортит символы.
- Уберите лишний вывод, если BOM не подтвердилсяОткройте первую строку подключённого PHP-файла и убедитесь, что до
<?phpнет вывода. Для файлов только с PHP обычно не нужен закрывающий?>в конце. Посмотрите, не вызван лиecho,var_dumpили подключение HTML до работы с сеансом и заголовками. Удаляйте только непреднамеренный вывод, сохраняя ожидаемую разметку страницы. - Проверьте синтаксис и HTTP-ответЗапустите
php -l путь/к/файлу.phpв терминале тестовой копии и проверьтеNo syntax errors detected. Откройте страницу в браузере, F12 → «Сеть», обновите страницу и проверьте код ответа и нужный заголовок/Set-Cookie. Если предупреждение пропало только из-за буферизации, это не доказательство устранения преждевременного вывода. - Откатите при повреждении кодировки или сессииЕсли после сохранения появились нечитаемые символы или пропали перенаправления, верните копию файла. Установите действительную кодировку исходника, а затем переведите его в UTF-8 без BOM через корректную процедуру. При повторной ошибке уточните файл и строку нового предупреждения; не включайте глобально ob_start как универсальное лечение.
#Проверяемый пример и команды
xxd -l 8 includes/config.phpphp -l includes/config.php<?php
// Разместите эту проверку до любого вывода в тестовом запросе.
if (headers_sent($file, $line)) {
error_log('Заголовки отправлены: ' . basename($file) . ':' . $line);
} else {
error_log('Заголовки пока не отправлены');
}#Проверка исправления и действия при неудаче
Успех подтверждается отсутствием предупреждения в закрытом логе, правильной работой header() и session_start(), а также наличием ожидаемого заголовка в HTTP-ответе. Если в начале файла нет EF BB BF, не считайте проблему решённой: ищите другой источник вывода.