php - отследить преждевременную утечку заголовков - PullRequest
0 голосов
/ 12 марта 2010

Я использую set_cookie () на сайте. После добавления некоторых функций я получаю ошибку Warning: Cannot modify header information - headers already sent by.... Номер строки, на которую он ссылается относительно того, откуда инициируются заголовки, это та самая строка, где set_cookie ()! И я проверил, он не вызывается дважды.

Как я могу отследить эти преждевременные заголовки? Я посмотрел на исходный код и не увидел каких-либо случайных символов или чего-либо еще до того, как появится сообщение об ошибке (я использую xdebug, поэтому первым делом является
, который, как я думал, был мной, но на самом деле это начало сообщения xdebug). Я набрал код для дополнительных echo и так далее - ничего.

Может ли PHP сказать мне, когда и где начинаются заголовки? Или они действительно начинаются с линии set_cookie, и если да, то как я оказался в этой ситуации и как мне выбраться?


edit: я не уверен, что могу вставить код - вы хотите просто строку set_cookie ()? Я думал, что заголовки выходили до этого. И до этого много чего происходит, когда создаются разные классы. А также я не думаю, что смогу публиковать все классы и прочее - вы знаете, частную информацию;)


Редактировать: я избавился от всех завершающих разделителей (все ?> с) и убедился, что первые символы каждого включенного файла <?. Это расстраивает! Это работало до того, как я сделал эти последние изменения: (((

Кроме того, почему headers_sent() не работает?

if ( headers_sent($filename, $linenum) ) { 
    echo "headers sent: $filename:$linenum."; 
}   
set_cookie(...); 

дает

headers sent: :0. 

Ответы [ 7 ]

7 голосов
/ 12 марта 2010

Вы можете использовать headers_sent():

if (!headers_sent($filename, $linenum)) {
    set_cookie(/*...*/);
} else {
    echo "Headers already sent in $filename on line $linenum\n";
    exit;
}
2 голосов
/ 12 марта 2010

Один из подходов состоит в том, чтобы запустить ваш скрипт из командной строки с перенаправлением STDERR на ноль.

Это покажет вам все, что отправляется в STDOUT, то есть все, что сервер отправит клиенту.

Надеюсь, как только вы увидите это, станет ясно, откуда берутся ваши заголовки.

1 голос
/ 12 марта 2010

Помимо использования headers_sent для определения того, был ли HTTP-заголовок уже отправлен, вы можете использовать PHP output control для буферизации вывода. Это позволяет вам изменить заголовок, даже если вы уже сделали какой-то вывод.

Вот несколько примеров использования явной буферизации вывода путем вызова ob_start:

ob_start();
echo 'foobar';
header('Content-Type: text/plain;charset=utf-8');

Но убедитесь, что вы позвонили ob_start до того, как был сделан какой-либо вывод. В противном случае заголовок HTTP, вероятно, уже отправлен.

0 голосов
/ 23 марта 2010

Я нашел это! Это был flush();, который я оставил валяться в одиночестве на одной из страниц. Удивительно, но он неправильно связывает $filename и $linenumber с headers_sent().

0 голосов
/ 12 марта 2010

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

0 голосов
/ 12 марта 2010

Вы уверены, что у вас нет никаких включаемых файлов, вызываемых до инициализации set_cookie ()? Есть ли у вас запущенные сеансы, потому что если вы это сделаете, вы можете просто установить cookie в тот же момент в вашем скрипте, когда вы начали сеанс.

0 голосов
/ 12 марта 2010

Можете ли вы вставить код?

Если заголовки произнесения уже отправлены [строкой, в которой находится set_cookie], то ошибка далее в скрипте.

...