Глиф Учебники

Cannot modify header information — headers already sent

Справочник · PHP · 2 минуты чтения

Текст
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
<?php
session_start();

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // обработка формы
    header('Location: /thanks.php');
    exit;
}
?>
<!DOCTYPE html>
<html lang="ru">

Что считается выводом

Если в скобках указана строка 1, почти наверняка виноваты пробел, пустая строка или BOM в начале файла.

Проверить заранее

Функция headers_sent говорит, отправлены ли заголовки, и где начался вывод:

PHP
<?php
if (headers_sent($file, $line)) {
    exit("Вывод начался в $file на строке $line");
}
header('Location: /login.php');
exit;

А если включить буферизацию?

ob_start() в начале скрипта копит весь вывод в памяти и отправляет его в конце, поэтому ошибка пропадает. На некоторых хостингах буферизация уже включена настройкой output_buffering, и тот же код работает там, но падает на другом сервере. Это обходной путь, а не исправление: надёжнее навести порядок — сначала заголовки, потом страница.