Cannot modify header information - headers already sent
С этой ошибкой ко мне постоянно обращаются и спрашивают: "Где ошибка?". Подобных писем за всё время я получил где-то штук 500, не меньше. Пора с ошибкой "Cannot modify header information - headers already sent" уже заканчивать. В этой статье я расскажу о причинах возникновения данной ошибки, а также о том, как её решить.
Если перевести данную ошибку на русский язык, то получится примерно следующее: "Нельзя изменить заголовок, поскольку они уже отправлены". Что это за "заголовки"? Давайте разберёмся.
Когда сервер возвращает ответ клиенту, помимо тела (например, HTML-кода страницы), идут ещё и заголовки. В них содержится код ответа сервера, cookie, кодировка и множество других служебных параметров. Может ли PHP-скрипт отправить заголовок? Конечно, может. Для этого существует функция header().
Данная функция, например, постоянно используется при редиректе. Также данная функция регулярно используется при генерации изображении в PHP.
Также заголовки модифицируются при отправке cookie и при начале сессии (функция session_start()).
А теперь о том, почему же всё-таки возникает ошибка? Сервер всегда сначала отдаёт серверу заголовки, а потом тело. Если сервер уже вернул заголовки, потом пошло тело, и тут он встречает какой-нибудь session_start(). Оказывается горе-программист забыл отправить заголовки до начала тела, и теперь хочет догнать уже ушедший поезд.
Вот код с ошибкой "Cannot modify header information - headers already sent":
<html>
<?php
session_start(); // А давайте начнём сессию
?>
Разумеется, такой бред PHP не прощает. И надо было писать так:
<?php
session_start(); // А давайте начнём сессию
?>
<html>
Вот этот скрипт уже не вызовет никаких ошибок, потому что сначала отправляются все заголовки, а уже потом идёт генерация тела ответа сервера.
Другой пример кода с ошибкой:
<?php
echo "Hello!"; // Что-нибудь выведем
session_start(); // А давайте начнём сессию
?>
То же самое, почему-то сначала выводится тело (либо его кусок), а потом вспомнили, что ещё и надо заголовки модифицировать.
Как будет правильно переписать данный код, подумайте сами.
Ещё пример:
<?php
$error = true; // Были ли ошибки?
if ($error) echo "Произошла ошибка";
header("Location: ".$_SERVER["HTTP_REFERER"]); // Делаем редирект обратно
exit;
?>
Когда у автора такого кода, ничего не получается, он удивляется от этой ошибки и говорит: "Очень странное совпадение, когда операция проходит успешно, всё хорошо, а когда какая-то ошибка, мне сообщают Cannot modify header information - headers already sent". Не дословно, но смысл именно в этом.
Проблема та же самая, и правильно писать так:
<?php
$error = true; // Были ли ошибки?
if ($error) echo "Произошла ошибка";
else header("Location: ".$_SERVER["HTTP_REFERER"]); // Делаем редирект обратно
exit;
?>
Есть и труднозаметные ошибки:
<?php
header("Location: ".$_SERVER["HTTP_REFERER"]); // Делаем редирект обратно
exit;
?>
Ошибка в данном коде возникает из-за пробела, который присутствует перед <?php. Пробел - это обычный символ, и он является частью тела ответа. И когда сервер его видит, он делает вывод о том, что заголовков больше не будет и пора выводить тело.
Бывают и следующие ошибки, имеющие всё ту же природу. Допустим есть файл a.html:
<?php echo "Hello"; ?>
Далее есть другой файл с таким кодом:
<?php
require_once "a.html";
header("Location: ".$_SERVER["HTTP_REFERER"]); // Делаем редирект обратно
exit;
?>
И человек искренне удивляется, откуда ошибка, если он ничего не выводил? Поэтому смотреть надо не конкретно 1 файл, а все файлы, которые подключаются в нём. И в тех, что подключаются у подключаемых, тоже надо смотреть, чтобы не было вывода.
И последний момент, но уже более сложный. Оказывается, что иногда эта ошибка происходит и при правильном коде. Тогда всё дело в кодировке. Убедитесь, что кодировка файла "UTF-8 без BOM", причём именно "без BOM", а не просто "UTF-8". Поскольку BOM - это байты, идущие в самом начале файла, и они являются выводом.
Очень надеюсь, что данная статья поможет решить абсолютно все проблемы, связанные с ошибкой "Cannot modify header information - headers already sent", поскольку я постарался осветить все возникающие проблемы. А дальше надо включить голову, и подумать, а что в Вашем коде не так?
-
- Михаил Русаков
Комментарии (10):
А я например использую ob_start() как и Михаил
Ответить
Интересная статья. спасибо.
Ответить
А у меня все примеры работают. Без ошибок.
Ответить
Михаил, подскажи мне, как сделать такую функцию. Вот допустим заходит человек с таким то ip, потом его перенаправляет на другой сайт? Вот мой код, правильно ли я написал? $ip = $_SERVER['REMOTE_ADDR']; if ($ip = '185.11.48.146'){ header('Location: http://myrusakov.ru/'); exit; }else{ header('Location: '.$_SERVER["HTTP_REFERER"]); exit; }
Ответить
В целом - верно
Ответить
А если код чистый, выровнял по строкам все что нужно. Движок на основе курса интернет магазина, какие еще могут быть проблемы? Может браузеры ошибки дают или другие варианты. Ругается именно на шаблонизатор и на сам хедер. Cannot modify header information - headers already sent by (output started at C:\Web\OpenServer\domains\localhost\lib\template_class.php:33) in C:\Web\OpenServer\domains\localhost\lib\reg_class.php on line 32
Ответить
Михаил, здравствуйте.то связано с тем, что браузеру уже были отправлены данные перед тем, как была вызвана одна из этих функций. Проверьте пожалуйста это. Так же часто случается из-за неверной кодировки. А, конкретнее происходят из-за использования BOM. Откройте пожалуйста каждый файл и сохраните в кодировке UTF-8 без BOM. Многие текстовые редакторы по умолчанию добавляют BOM ко всем файлам юникодовской кодировкой. Из-за кодировки получается "лишний код" который же отправятся к браузеру ещё до начала интерпретации нужного PHP-кода. Так же можно запретить текстовому редактору сохранять BOM. Но тут уже всё зависит от возможностей текстового редактора, который вы используете. Например, я пользуюсь Notepad++... там можно открыть меню "Кодировки" и выбрать "Преобразовать в UTF-8 без BOM". Если же Вы уверены, что кодировка чистая UTF-8 без BOM, то проверьте вручную, значит Вы где-то сами отправляете данные перед функциями header(), setcookie() и т.п.
Ответить
вот задание по основным функциям php 17. реализация редиректа, как реализовать если Русаков даёт только информацию о том как передавать заголовки и не более того!? пытался принять данные из формы в другом файле, а из него на index.php делал редирект. ничего не выходит. может кто-то поможет по-человечески?
Ответить
Здравствуйте! А если мне всё-таки нужно вставить php-файл с header в тело html. Напишите, пожалуйста, можно ли заменить чем-то header("Location:".$_SERVER["HTTP_REFERER"]);
Ответить
<?php session_start(); require_once "lib/functions.php"; ?> Вот мой код. Правильно написал его в поле start?
Ответить
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.