Cannot modify header information — headers already sent
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/index.php:1) in /var/www/html/index.php on line 5Ответ сервера состоит из двух частей: сначала заголовки (служебные строки: куда перенаправить, какие cookie поставить), потом само содержимое страницы. Как только PHP выводит первый символ страницы — даже пробел, — он отправляет заголовки. После этого header(), setcookie() и session_start() изменить их уже не могут.
Главное в сообщении — часть в скобках: output started at /var/www/html/index.php:1. Это файл и строка, где начался вывод. Откройте именно это место.
Решение: сначала логика, потом вывод
Всё, что работает с заголовками, ставьте в начало файла — до HTML и до любого echo:
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// обработка формы
header('Location: /thanks.php');
exit;
}
?>
<!DOCTYPE html>
<html lang="ru">Что считается выводом
echo,print, HTML до вызоваheader().- Пробел или пустая строка перед
<?php. Её не видно, но это тоже вывод.<?phpдолжен стоять в первой строке с первого символа. - Пустая строка после
?>в подключённом файле (config.php,functions.php). Поэтому в файлах только с кодом закрывающий?>не пишут вовсе. - BOM — невидимая метка в начале файла, которую добавляют некоторые редакторы при сохранении в «UTF-8 with BOM». Сохраните файл в кодировке UTF-8 без BOM: в Visual Studio Code — щелчок по названию кодировки в строке состояния внизу, «Save with Encoding», затем «UTF-8».
- Сообщение об ошибке. Если до вызова
header()случилось предупреждение и показ ошибок включён, текст предупреждения сам стал выводом. Исправьте первую ошибку — исчезнет и эта.
Если в скобках указана строка 1, почти наверняка виноваты пробел, пустая строка или BOM в начале файла.
Проверить заранее
Функция headers_sent говорит, отправлены ли заголовки, и где начался вывод:
<?php
if (headers_sent($file, $line)) {
exit("Вывод начался в $file на строке $line");
}
header('Location: /login.php');
exit;А если включить буферизацию?
ob_start() в начале скрипта копит весь вывод в памяти и отправляет его в конце, поэтому ошибка пропадает. На некоторых хостингах буферизация уже включена настройкой output_buffering, и тот же код работает там, но падает на другом сервере. Это обходной путь, а не исправление: надёжнее навести порядок — сначала заголовки, потом страница.