Решение проблемы "Cannot add header information - headers already sent". Что такое Http заголовки (Http headers)

Удивительно сколь малая ошибка может привести в полностью нерабочее состояние ваш сайт на WordPress. Мы говорим, конечно же, об известной ошибке-предупреждении WordPress Warning: cannot modify header information — headers already sent by pluggable.php (не удаётся изменить информацию заголовка) . Если вы один из тех, кто столкнулся с этой ошибкой, тогда вы пришли по адресу. В этом мы обсудим прежде всего причину появления этой ошибки и посмотрим на пути решения, которые позволят окончательно решить проблему.

Что потребуется

Перед стартом убедитесь в наличии следующего:

  • Доступ к вашей панели управления хостингом или FTP доступ

Как возникает ошибка Cannot modify header information — headers already sent by

Давайте рассмотрим пример этой ошибки, чтобы лучше понять причины. Ошибка обычно появляется в такой форме:

Warning: Cannot modify header information - headers already sent by (output started at /public_html/wp-content/plugins/my-plugin/my-function.php:#) in /public_html/wp-includes/pluggable.php on line #

Как видите, в ошибке упоминается два файла. Первый файл (в нашем случае: my-function.php размещённый в /public_html//wp-content/plugins/my-plugin/ ) во главе подозреваемых. Это наш пользовательский код, который предназначен для изменения функциональности ядра, обеспечиваемой WordPress. Функциональность ядра находится в файле pluggable.php (файл ядра WordPress, неизменный для любой установки WordPress). Иными словами, проблема в первом файле, который не даёт второму файлу выполняться должным образом.

Основной причиной ошибки являются лишние пробелы в первом файле . Это пробелы вверху или внизу файла, ненужные пробелы где угодно в файле или даже пробелы в PHP-тегах . К слову, по причине того, что программисты могут (и обычно так и происходит) ошибочно вбивать лишние пробелы в свой код, эта ошибка наиболее часто возникает, чем можно ожидать. Строка #, указанная в сообщении об ошибке, ссылается на место расположения проблемы – это поможет устранить проблему быстрее и без суеты.

Исправление ошибки cannot modify header information — headers already sent by

Теперь, когда вы знаете, что вызывает ошибку, вы можете перейти к её исправлению. Мы покажем вам два варианта устранения проблемы, которые вы можете попробовать по отдельности или по очереди, если по отдельности не помогло.

Вариант 1 – Редактирования неисправного файла

Первый вариант решения ошибки Warning: cannot modify header information – ручное исправление файла с ошибкой. Вы уже имеете в наличии необходимую информацию, для нахождения проблемы в самом сообщении об ошибке (помним, это первый файл в сообщении). Всё, что потребуется – это открыть этот файл по FTP, используя клиент вроде FileZilla или через файловый менеджер .

По существу, всё, о чём здесь нужно позаботиться – это убрать лишние пробелы/пустые строки в файле. Хорошее место для начала будет строка #, упомянутая в сообщении об ошибке. С этого места вы можете продолжить разбор остального файла в поисках других ненужных пробелов или пустых строк до самого конца документа.

Убедитесь в правильности написания начального и завершающего тегов PHP. Не должно быть пробела до или после тега , также как и тега ?> . Также, последняя строка кода не должна завершаться пробелом или лишнем переводом строки.

На скриншоте ниже вы можете увидеть файл wp-config.php , в котором есть пробелы перед первым тегом PHP.


ПОДСКАЗКА : Во многих текстовых редакторах удалить ненужные пробелы можно автоматически. Например, для удаления лишних пробелов в редакторе Atom , выделите весь код и перейдите в Packages -> Whitespace -> Remove Trailing Whitespace .

Вариант 2 – Заменить неисправный файл

Конечно, редактирование целого ряда файлов с ошибками может вызвать затруднение. Файлы могут относиться к плагину или теме, которые вы только что установили на своём сайте или даже могут быть файлами ядра WordPress.

Если ошибка действительно вызвана плагином или темой, всё что потребуется сделать – это переустановить его/её. Это действие в большинстве случаев помогает. С другой стороны, если файл ядра WordPress причина ошибки, лучшим решением взять чистую копию WordPress и заменить файл с ошибкой в вашей установке на такой же в исправной версии. Это будет гарантировать, что неисправный файл восстановлен в исходное состояние, в то время как остальная установка вашего сайта WordPress останется в целости и сохранности. Теперь, просто перезагрузите страницу и убедитесь, что ошибка исправлена.

В завершение

Независимо от того, вставили ли вы фрагмент кода в файл, добавили новый плагин/тему или написали код вручную, существует риск появления лишних пробелов в файле. Эти, казалось бы невинные пробелы, могут обернуться ошибкой WordPress Warning: cannot modify header information — headers already sent by .

В этом руководстве, мы рассмотрели как исправлять такие ошибки, и теперь ваш сайт опять работает как и положено. Больше руководств по WordPress можно найти .

Автор

Елена имеет профессиональное техническое образование в области информационных технологий и опыт программирования на разных языках под разные платформы и системы. Более 10 лет посвятила сфере веб, работая с разными CMS, такими как: Drupal, Joomla, Magento и конечно же наиболее популярной в наши дни системой управления контентом – WordPress. Её статьи всегда технически выверены и точны, будь то обзор для WordPress или инструкции по настройке вашего VPS сервера.

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

Все статьи из цикла:

  • Что такое Http заголовки. Общая теория.

HTTP расшифровывается как HyperText Transfer Protocol (протокол передачи гипертекста). Протокол — это набор правил, по которым разные устройства обмениваются данными. Он был создан в 1990-х годах. Сейчас он используется в сети интернет практически повсеместно. Всё, что вы видите в окне браузера, было получено посредством этого протокола. http заголовки — пожалуй главная вещь в общении между устройствами. Они передают основную информацию об устанавливающемся соединении и о передаваемой информации через это соединение.
Взглянем на схему общения двух устройств. Пусть этими устройствами будут ваш компьютер и какой-нибудь сервер в интернете:

Как видно, браузер отослал http-запрос. Он может выглядеть примерно так:

GET /other-19 HTTP/1.1
Host: www.scriptsite.ru
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

При этом первая строка является строкой запроса, все остальные строки — это и есть http-заголовки, несущие в себе дополнительную информацию о запросе, о клиенте, который эту инфомрацию запрашивает, о многих других вещах.
В ответ на наш запрос сервер может отослать такие заголовки:

Server: Apache/2.0.61 (Unix) mod_ssl/2.0.61 OpenSSL/0.9.8k mod_dp20/0.99.2 PHP/5.2.5 mod_python/3.3.1 Python/2.5.1 mod_ruby/1.2.6 Ruby/1.8.6(2007-09-24)

X-Powered-By: PHP/5.2.5

Set-Cookie: PHPSESSID=ft47gokfee6amv3eda3k1p93s3; path=/

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

Pragma: no-cache

Keep-Alive: timeout=10, max=1024

Connection: Keep-Alive

Transfer-Encoding: chunked

Content-Type: text/html

Первая строка — строка статуса. Остальные строки — заголовки. В схеме было показано, что подгружается ещё и содержимое страницы. Но это содержимое обычно не принято отображать в плагинах, просматривающих заголовки. Да и содержимое страницы — это только частный случай. По протоколу же не обязательно страница должна передаваться. Вместо неё могут быть переданы и картинка, и звуковой файл, и видео. И у всех них заголовки будут сильно отличаться.

Как увидеть http-заголовки?

Для того, чтобы увидеть http-заголовки, я рекомендую следующие плагины для браузера firefox:

Если вы пользуетесь браузером Chrome, просмотреть всю информацию можно, нажав на кнопку настройки — инструменты — инструменты разработчика. Вкладка networks.
Пользователям браузера opera ничего посоветовать не могу, так как не дружу с этим браузером. Установив плагины и запустив их, попробуйте обновить страницу. Вы сразу же увидите огромные списки запросов и ответов, посредством которых ваш браузер общался с сервером.

Http-заголовки и доступ к ним в php

Если вы являетесь php-разработчиком, вы можете получить доступ к заголовкам запроса с помощью функции getallheaders() . Для понимания её работы выполним такой код:

И мы получаем распечатку массива заголовков.

Но чаще к ним обращаются через глобальную переменную $_SERVER. Почти для каждого http заголовка есть аналогичное название элемента в этой переменной, образуемого по принципу HTTP_имя_заголовка. Так для того же ‘User_Agent’ есть переменная $_SERVER[‘HTTP_USER_AGENT’];

Для получения заголовков, которые сервер собирается отправить пользователю, используется функция headers_list() . Как правило, сервер составляет недостающие обязательные заголовки уже в конце работы всех скриптов. Поэтому этот массив будет содержать заголовки либо те, которые сервер создал перед началом выполнения скрипта (и они не будут изменены), либо те, которые мы установили вручную. Вручную их можно установить с помощью функции header(«текст заголовка»);
Выполним такой код:

Увидим распечатку готовых к отправке на момент вызова функции заголовков:

Первый заголовок был установлен автоматически, и он несёт в себе название сервера, на котором выполняется скрипт. Второй - установленный нами вручную. Если бы браузеру нужен был заголовок «Фрукт», он бы взял его из http-ответа сервра и использовал. Но так как наш браузер не нуждается в нём, то он просто игнорирует непонятную ему строку.

Структура http запроса

Наш запрос выглядит следующим образом:

Первая строка в нём, как уже было сказано раньше, является строкой запроса. Она состоит из трёх частей:

  • method (метод) — указывает, какого рода запрос. Самые распространённые методы: GET, POST, HEAD. О них будет написано в следующем параграфе.
  • path (путь) — как правило, это часть URL, идущая после домена. Например, если вы вводите в адресную строку http://www.scriptsite.ru/about/, значение path будет /about/.
  • protocol (протокол) — используемый протокол. Как правило, состоит из «HTTP» и версии протокола. Обычно, в современных браузерах используется версия 1.1

Дальше идут заголовки в виде строк формата «Имя: значение».
Кстати, данные о cookies также передаются в этом запросе в виде одного из заголовков. Большинство из этих строк не являются обязательными. Запрос может быть сокращён вообще до двух строк:

GET /article/show/4/ HTTP/1.1

Host: scriptsite.ru

Методы запроса

GET

get-запрос обычно используется для запроса документа с передачей некоторых параметров.
Это основной метод, используемый для получения html-страниц, изображений, CSS и JavaScript файлов, и т.д.
Из-за того, что параметры могут быть любыми, а на сервере нет ограничений по способам их обработки, часто метод для запросов данных используют для передачи информации. Например, у нас будет такая форма

При этом эти параметры будут видны в адресной строке браузера.

POST

Post — метод, используемый для отправки данных на сервер. Несмотря на то, что вы можете отправлять данные серверу методом GET через адресную строку браузера, в большинстве случаев предпочтительнее использовать POST. Отправлять большие объёмы данных через GET непрактично. К тому же GET имеет некоторые ограничения, не позволяющие, например, опубликовать эту статью на моём сайте через одну лишь строку браузера. POST запросы чаще всего используются для передачи web-форм. Давайте изменим форму из предыдущего примера, задав ей метод POST

Это сообщение об ошибке часто встречают программисты, начинающие использовать PHP. Понимание того, почему возникает эта ошибка, поможет найти решение.

PHP делает много работы по генерации веб-страниц за вас, даже без вашей просьбы. Веб-страница состоит из двух частей: заголовка и тела.

Эта распространенная ошибка PHP наблюдается когда программист делает ошибки в манипуляции или создания заголовков. Вот пример:

Warning: Cannot modify header information – headers already sent by (output started at /home/usr1/public_html/sent.php:42) in /home/usr1/public_html/includes/theme-header.php on line 12

Как правило, вам не нужно беспокоиться о заголовке, так как он генерируется автоматически и содержит информацию о странице, сервере, и coockie. Информация в заголовке важна, но она обычно не видна пользователю. Вот несколько примеров:

Date: Mon, 10 Jul 2006 18:51:59 GMT Server: Apache/2.2.0 (Unix) mod_ssl/2.2.0 OpenSSL/0.9.7g Content-Encoding: gzip Content-Type: text/html

Иногда программисты хотят изменить некоторые значения заголовка. Например, если PHP генерирует XML вывод, Content-Type должен быть изменен, чтобы указать это. Другим распространенным примером является перенаправление браузера пользователя на другую веб-страницу с помощью элемента заголовка Location, как описано в этой статье .

Заголовок должен идти первым в ответе с веб-сервера и отделяется от тела одной пустой строкой. Причиной этой ошибки является то, что некоторая часть тела веб-страницы была отправлена ​​пользователю уже до того, когда делается попытка установить значение заголовка. Поскольку PHP упрощает многие вещи для вас, проблема может скрываться в обычном месте. Вот некоторые указания для нахождения проблемы:

  1. Найдите инструкцию header(), которая является причиной проблемы. Ошибка должна быть на или до этой линии.
  2. Посмотрите на любые инструкции, которые могли бы направить вывод пользователю до этой инструкции заголовка. Если вы обнаружили один или несколько, измените код, чтобы переместить инструкцию заголовка перед ними. Сложные условные операторы могут усложнить проблему, но они также могут помочь решить проблему. Как вариант можете применить условное выражение в верхней части сценария PHP, которое определяет значение заголовка как можно раньше, и устанавливает его там.
  3. Убедитесь, что нет пробелов за пределами начального и конечного PHP тэгов. В то время как пустая строка перед начальным тегом
  4. Если вы сохраняете ваш файл в кодировке UTF-8, то убедитесь, что файл сохраняется без сигнатуры (without BOM). Сигнатура — это байт, добавляемый в начале файла, и если PHP скрипт сохранить в таком формате, то этот байт будет воспринят как часть вывода тела страницы, чего нельзя допускать во избежание рассматриваемой нами проблемы.

С этой ошибкой ко мне постоянно обращаются и спрашивают: "Где ошибка? ". Подобных писем за всё время я получил где-то штук 500 , не меньше. Пора с ошибкой "" уже заканчивать. В этой статье я расскажу о причинах возникновения данной ошибки, а также о том, как её решить.

Если перевести данную ошибку на русский язык, то получится примерно следующее: "Нельзя изменить заголовок, поскольку они уже отправлены ". Что это за "заголовки "? Давайте разберёмся.

Когда сервер возвращает ответ клиенту, помимо тела (например, HTML-кода страницы), идут ещё и заголовки. В них содержится код ответа сервера, cookie , кодировка и множество других служебных параметров. Может ли PHP-скрипт отправить заголовок? Конечно, может. Для этого существует функция header() .

Данная функция, например, постоянно используется при . Также данная функция регулярно используется при .

Также заголовки модифицируются при отправке cookie и при начале сессии (функция session_start() ).

А теперь о том, почему же всё-таки возникает ошибка? Сервер всегда сначала отдаёт серверу заголовки, а потом тело. Если сервер уже вернул заголовки, потом пошло тело, и тут он встречает какой-нибудь session_start() . Оказывается горе-программист забыл отправить заголовки до начала тела, и теперь хочет догнать уже ушедший поезд.

Вот код с ошибкой "":



?>

Разумеется, такой бред PHP не прощает. И надо было писать так:

session_start(); // А давайте начнём сессию
?>

Вот этот скрипт уже не вызовет никаких ошибок, потому что сначала отправляются все заголовки, а уже потом идёт генерация тела ответа сервера.

Другой пример кода с ошибкой:

echo "Hello!"; // Что-нибудь выведем
session_start(); // А давайте начнём сессию
?>

То же самое, почему-то сначала выводится тело (либо его кусок), а потом вспомнили, что ещё и надо заголовки модифицировать.

Как будет правильно переписать данный код, подумайте сами.

Ещё пример:




exit;
?>

Когда у автора такого кода, ничего не получается, он удивляется от этой ошибки и говорит: "Очень странное совпадение, когда операция проходит успешно, всё хорошо, а когда какая-то ошибка, мне сообщают Cannot modify header information - headers already sent". Не дословно, но смысл именно в этом.

Проблема та же самая, и правильно писать так:

$error = true; // Были ли ошибки?
if ($error) echo "Произошла ошибка";
else header("Location: ".$_SERVER["HTTP_REFERER"]); // Делаем редирект обратно
exit;
?>

Есть и труднозаметные ошибки:

header("Location: ".$_SERVER["HTTP_REFERER"]); // Делаем редирект обратно
exit;
?>

Ошибка в данном коде возникает из-за пробела , который присутствует перед . Пробел - это обычный символ, и он является частью тела ответа. И когда сервер его видит, он делает вывод о том, что заголовков больше не будет и пора выводить тело.

Бывают и следующие ошибки, имеющие всё ту же природу. Допустим есть файл a.html :

require_once "a.html";
header("Location: ".$_SERVER["HTTP_REFERER"]); // Делаем редирект обратно
exit;
?>

И человек искренне удивляется, откуда ошибка, если он ничего не выводил? Поэтому смотреть надо не конкретно 1 файл, а все файлы, которые подключаются в нём. И в тех, что подключаются у подключаемых, тоже надо смотреть, чтобы не было вывода.

И последний момент, но уже более сложный. Оказывается, что иногда эта ошибка происходит и при правильном коде. Тогда всё дело в кодировке . Убедитесь, что кодировка файла "UTF-8 без BOM ", причём именно "без BOM ", а не просто "UTF-8 ". Поскольку BOM - это байты, идущие в самом начале файла, и они являются выводом.

Очень надеюсь, что данная статья поможет решить абсолютно все проблемы, связанные с ошибкой "", поскольку я постарался осветить все возникающие проблемы. А дальше надо включить голову, и подумать, а что в Вашем коде не так?

Ошибку эту исправить несложно.
Часто такое же сообщение появляется при старте сессий, в немного другой формулировке:
Warning: Cannot send session cookie - headers already sent
Warning: Cannot send session cache limiter - headers already sent

Byte Order Mark
Иногда вы проверили ВСЁ - нигде ничего нет. Смените редактор. Посмотрите свой файл в другой программе. К примеру, Windows Блокнот при использовании кодировки Unicode добавляет в начало вашего файла служебный символ Byte Order Mark , никак при этом не ставя вас в известность. Откройте скрипт в другом редакторе и удалите посторонние символы. И смените Блокнот на другой редактор.
Или сохраняйте в кодировке UTF-8 without BOM

Многочисленные вопросы на форуме заставляют меня сделать здесь важное замечание:
Эта ошибка появляется не от того, что у вас в скрипте "что то написано выше". А от того, что РНР выводит что-то в браузер. Это не обязательно код. Это может быть сообщение об ошибке . может быть пробел или хтмл тег. Да-да. Для самых талантливых: речь идет о любом символе, отправленном в браузер, а не только о тех, которые браузер отображает неискушенному пользователю. У HTML страниц есть исходный текст. И именно он является результатом работы PHP скрипта, а не красивые буковки с картиночками, как думает очень большое количество людей.


© 2024, applelavka.ru - Изучаем компьютер. Просто о сложном. Гаджеты