<MyRusakov.ru />

Создание движка на PHP и MySQL 2.0

Создание движка на PHP и MySQL 2.0

Видеокурс "Создание движка на PHP и MySQL 2.0" научит Вас создавать профессиональные движки для сайтов на PHP и MySQL с использованием ООП и паттерна MVC.

В курсе разобрана вся теория по структуре движка: как всё устроено, какие должны быть объекты, какая у них иерархия и как они взаимодействуют между собой.

В практической части будет создан движок с чистого листа. Будет создано ядро, все адаптеры, все вспомогательные классы, а также классы для работы с объектами базы данных. И чтобы курс был максимально полезным, будет создан движок для сайта MyRusakov.ru.

Подробнее
Подписка

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Каким движком Вы предпочитаете пользоваться?

Cannot modify header information - headers already sent

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", поскольку я постарался осветить все возникающие проблемы. А дальше надо включить голову, и подумать, а что в Вашем коде не так?

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (10):

malina95 malina95 24.12.2012 12:50:01

А я например использую ob_start() как и Михаил

Ответить

neve4 neve4 24.12.2012 14:24:43

Интересная статья. спасибо.

Ответить

ankalitkin ankalitkin 01.01.2013 19:12:40

А у меня все примеры работают. Без ошибок.

Ответить

Dima2000%. Dima2000%. 14.12.2013 17:57:36

Михаил, подскажи мне, как сделать такую функцию. Вот допустим заходит человек с таким то ip, потом его перенаправляет на другой сайт? Вот мой код, правильно ли я написал? $ip = $_SERVER['REMOTE_ADDR']; if ($ip = '185.11.48.146'){ header('Location: http://myrusakov.ru/'); exit; }else{ header('Location: '.$_SERVER["HTTP_REFERER"]); exit; }

Ответить

alexandrdante alexandrdante 14.12.2013 18:42:57

В целом - верно

Ответить

Jersie Jersie 05.02.2014 02:16:09

А если код чистый, выровнял по строкам все что нужно. Движок на основе курса интернет магазина, какие еще могут быть проблемы? Может браузеры ошибки дают или другие варианты. Ругается именно на шаблонизатор и на сам хедер. 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

Ответить

tikkiwiki tikkiwiki 12.02.2014 11:56:13

Михаил, здравствуйте.то связано с тем, что браузеру уже были отправлены данные перед тем, как была вызвана одна из этих функций. Проверьте пожалуйста это. Так же часто случается из-за неверной кодировки. А, конкретнее происходят из-за использования BOM. Откройте пожалуйста каждый файл и сохраните в кодировке UTF-8 без BOM. Многие текстовые редакторы по умолчанию добавляют BOM ко всем файлам юникодовской кодировкой. Из-за кодировки получается "лишний код" который же отправятся к браузеру ещё до начала интерпретации нужного PHP-кода. Так же можно запретить текстовому редактору сохранять BOM. Но тут уже всё зависит от возможностей текстового редактора, который вы используете. Например, я пользуюсь Notepad++... там можно открыть меню "Кодировки" и выбрать "Преобразовать в UTF-8 без BOM". Если же Вы уверены, что кодировка чистая UTF-8 без BOM, то проверьте вручную, значит Вы где-то сами отправляете данные перед функциями header(), setcookie() и т.п.

Ответить

evolution10121987 evolution10121987 31.03.2015 09:43:58

вот задание по основным функциям php 17. реализация редиректа, как реализовать если Русаков даёт только информацию о том как передавать заголовки и не более того!? пытался принять данные из формы в другом файле, а из него на index.php делал редирект. ничего не выходит. может кто-то поможет по-человечески?

Ответить

Yuliya Yuliya 07.04.2014 10:15:42

Здравствуйте! А если мне всё-таки нужно вставить php-файл с header в тело html. Напишите, пожалуйста, можно ли заменить чем-то header("Location:".$_SERVER["HTTP_REFERER"]);

Ответить

vladimirhomenko155 vladimirhomenko155 11.03.2016 19:27:28

<?php session_start(); require_once "lib/functions.php"; ?> Вот мой код. Правильно написал его в поле start?

Ответить

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.