Cannot modify header information - headers already sent by

Ошибка: Cannot modify header information - headers already sent by

Ошибка PHP Cannot modify header information - headers already sent by - самая распространенная и самая непонятная для начинающих программистов. Обычно, с ней сталкиваются, когда пишут свой первый сайт на PHP, реже, когда второй или третий. И тут же пишут на всех форумах: "Аааааааа! У меня ничего не работает! Помогите! Что значит headers already sent by???
Я даже видел форум, у которого на странице регистрации крупными красными буквами было написано что-то вроде "Если вы хотите зарегистрироваться только чтобы спросить, что такое Cannot modify header information, то идите сначала в FAQ и читайте!!!" Видимо сильно достали админов этим вопросом.

Ошибка Cannot modify header information в WordPress

Немного теории: что такое Header Information и почему ее Cannot Modify

Заголовки (Headers) - это служебная информация, которую отправляет сервер, на котором работает сайт, браузеру пользователя. Даже если вы написали PHP-скрипт из одной строчки

	<?php
	
	echo "Hello, World!";
	
	?>
	

все равно, сначала браузеру отправляется дополнительная информация, например о том, что страница доступна для просмотра, установленные cookies, какая у страницы кодировка, имя сервера и многое другое. И только потом - основное содержание, т.е. фраза "Hello, World!".

Эти заголовки пользователь конечно не видит, но они нужны браузеру, чтобы корректно отобразить эту вашу страницу. Так вот, после того, как эти заголовки (Header information) отправлены и началась передача основного содержания страницы, их изменить или дополнить нельзя. Иначе получится как в том анекдоте - "Хотели тебе отправить немного денег, но уже запечатали конверт"

Но до того, как началась передача основного содержания, заголовки изменить можно. Для этого в PHP есть специальная функция Header(). Например, можно отправить заголовок, сообщающий о типе содержимого и кодировке страницы

	<?php
	
	Header("Content-Type: text/html; charset=windows-1251"); 
	
	?>
	

Так вот, если начать отправлять заголовки после того, как частично или полностью отправлено основное содержание страницы, и возникает ошибка Cannot modify header information - headers already sent by (Невозможно изменить информацию в заголовке - заголовки уже были отправлены)

Причины возникновения ошибки Cannot modify header information - headers already sent by

Первая причина ошибки Cannot modify header information - самая очевидная

Да, самая очевидная причина этой ошибки - неопытный программист использует функцию Header() или пытается установить cookies после того, как начал выводить основное содержание:

	<?php
	
	echo "Hello, World!";
	
	Header("Content-Type: text/html; charset=windows-1251"); 
	
	?>
	
или
	<html>
	<head>
	...
	</head>
	<body>
	
	<?php
	
	setcookie('my_cookie_var', 'hello word');
	
	?>
	</body>
	</html>
	

Или, сообщив пользователю "Hello world" пытается отправить его на другую страницу, например "byeworld.php", тоже используя функцию Header():

	<?php
	
	echo "Hello, World!";
	
	Header("Location: byeworld.php"); 
	
	?>
	

Вторая причина ошибки headers already sent by - неочевидная

Уже более опытный программист, делая второй или третий сайт, зная, что выводить заголовки после основного содержания нельзя, все равно в какой-то момент получает Warning: Cannot modify header information - headers already sent by. Смотрит свой код, видит, что функция Header() или установка cookies всегда в самом начале, долго не может понять в чем дело, и снова идет на форум задать вопрос "Что за фигня, Header() в самом начале кода, а все равно получаю Cannot modify header information!"

В 99% случаев ошибка из-за того, что:

а) Отправка основного содержания уже началась, т.к. перед тегом <?php вставлена пустая строка или пробел.
А все, что перед <?php - интерпретируется как HTML-код основного содержания

	_____________пустая строка_____________
	___пробел___<?php
	
	Header("Content-Type: text/html; charset=windows-1251"); 
	
	?>
	

б) В начале файла подключается другой файл, в котором идет отправка основного содержания либо явно (функциями echo или print), либо неявно, как в предыдущем варианте с пробелом или пустой строкой

	<?php
	
	include("functions.php");
	
	setcookie('my_cookie_var', 'hello word');
	
	?>
	
	<?php
	// functions.php
	
	function my_func()
		{
		
		}
	
	echo "Hello, World!";
	
	?>
	

Так что надо проверить все файлы, в т.ч. подключаемые, на наличие таких пробелов или пустых строк перед началом кода PHP

в) Почти вариант а), но такой, что заметить этот дополнительный пробел крайне сложно. Дело в том, что свой файл PHP вы можете создать в кодировке UTF-8, и некоторые редакторы кода в начало файла запишут дополнительный специальный символ, идентификатор UTF-8 (BOM - byte order mark). В редакторе он отображаться не будет, а вот сервер, который будет обрабатывать этот файл, может его принять просто за одиночный символ и вывести его сразу после заголовков. Этот символ тоже может вообще никак не отобразиться в браузере, но если посмотреть исходный код страницы, можно увидеть дополнительный отступ или знак "?" перед основным содержимым (обычно перед тегом BODY) Соответственно, если такой символ выводится, а в файле есть функция Header(), то это и приведет к появлению ошибки Cannot modify header information - headers already sent by. Увидеть этот символ, в виде знака ?, квадратика или пробела можно, открыв файл в обычном блокноте. Чтобы избавиться от этой проблемы, в настройках своего редактора PHP найдите и отключите вставку этого идентификатора.

Оставшийся 1% случаев - это неправильные настройки сервера или PHP интерпретатора. Скорее всего вы с этим вряд ли столкнетесь.


Вот вкратце и все. Надеюсь, что эта страница поможет вам понять, из-за чего возникает ошибка Cannot modify header information и избежать бессонных ночей в поисках решения, где же эти чертовы headers alredy sent by