PHP LinuxWindowsmacOS

PHP: ошибка Headers already sent из-за BOM в подключённом файле

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

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

PHP Headers already sent из-за BOM: как найти EF BB BF в подключённом PHP-файле, убрать метку без повреждения текста и проверить отправку cookie и заголовков.

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

#Когда возникает ошибка

Ошибка 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 только фиксирует место начала.В сообщении указан другой файл/строка, чем предполагаемый конфиг.Проверьте фактическое место, где начался вывод.

#Пошаговая диагностика и устранение

  1. Уточните оба файла из сообщенияВ закрытом журнале найдите строку headers already sent by (путь:строка) и место, где вызвали header()/session_start(). Откройте оба файла. Если сообщение указывает на строку 1 подключённого файла, это характерно для BOM, но не доказательство: сначала посмотрите начало файла и наличие случайного вывода.
  2. Сохраните резервную копию перед изменениемСкопируйте проблемный PHP-файл и зафиксируйте его текущую кодировку. В редакторе Visual Studio Code откройте «Файл» → «Открыть файл» и выберите именно файл, указанный в журнале. Если работаете по SSH, скопируйте файл в закрытую служебную папку или воспользуйтесь управлением версиями. Не меняйте все PHP-файлы пакетно.
  3. Проверьте начальные байты файлаВ терминале Linux выполните xxd -l 8 путь/к/файлу.php при наличии xxd или откройте файл шестнадцатеричным просмотрщиком в редакторе. Если вывод начинается ef bb bf 3c 3f 70 68 70, это BOM перед <?php. Если начинается сразу 3c 3f 70 68 70, BOM там нет — ищите пробелы, HTML или преждевременный вывод в другом файле.
  4. Сохраните файл как UTF-8 без BOMВ Visual Studio Code нажмите обозначение кодировки справа в строке состояния → «Сохранить с кодировкой» → «UTF-8» (не «UTF-8 with BOM»). Проверьте, что текст на русском сохранился без искажений. Внимание: если исходный файл был в Windows-1251, сначала определите действительную кодировку — обычная смена метки сохранения без корректного чтения испортит символы.
  5. Уберите лишний вывод, если BOM не подтвердилсяОткройте первую строку подключённого PHP-файла и убедитесь, что до <?php нет вывода. Для файлов только с PHP обычно не нужен закрывающий ?> в конце. Посмотрите, не вызван ли echo, var_dump или подключение HTML до работы с сеансом и заголовками. Удаляйте только непреднамеренный вывод, сохраняя ожидаемую разметку страницы.
  6. Проверьте синтаксис и HTTP-ответЗапустите php -l путь/к/файлу.php в терминале тестовой копии и проверьте No syntax errors detected. Откройте страницу в браузере, F12 → «Сеть», обновите страницу и проверьте код ответа и нужный заголовок/Set-Cookie. Если предупреждение пропало только из-за буферизации, это не доказательство устранения преждевременного вывода.
  7. Откатите при повреждении кодировки или сессииЕсли после сохранения появились нечитаемые символы или пропали перенаправления, верните копию файла. Установите действительную кодировку исходника, а затем переведите его в UTF-8 без BOM через корректную процедуру. При повторной ошибке уточните файл и строку нового предупреждения; не включайте глобально ob_start как универсальное лечение.

#Проверяемый пример и команды

Linux · Терминал (Bash)Команда
В терминале тестового проекта. Замените путь на файл из журнала; xxd установлен не везде. Первая команда читает первые 8 байт, вторая проверяет синтаксис. Прав администратора не нужно.
xxd -l 8 includes/config.php
php -l includes/config.php
PHP
Выполните в приватном тестовом обработчике. Сведения пишутся в журнал сервера, а не посетителю; результат может зависеть от буферизации и не заменяет анализа первых байтов.
<?php
// Разместите эту проверку до любого вывода в тестовом запросе.
if (headers_sent($file, $line)) {
    error_log('Заголовки отправлены: ' . basename($file) . ':' . $line);
} else {
    error_log('Заголовки пока не отправлены');
}

#Проверка исправления и действия при неудаче

Успех подтверждается отсутствием предупреждения в закрытом логе, правильной работой header() и session_start(), а также наличием ожидаемого заголовка в HTTP-ответе. Если в начале файла нет EF BB BF, не считайте проблему решённой: ищите другой источник вывода.

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

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