php Почему не работает редирект Warning: Cannot modify header information - headers already sent by... Ошибка Решение
Primary tabs
[продолжение этого вопроса]
Описание частной проблемы
После нажатия на кнопку выводится ошибка:
Warning: Cannot modify header information - headers already sent by (output started at C:\OpenServer\domains\testsite\WEB\5_phpRedirect.php:10) in C:\OpenServer\domains\testsite\WEB\5_phpRedirect.php on line 12
Код аналогичен приведённому в данной теме:
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title> Экспериментальный Web </title> </head> <body> <H1> Выберите скрипт для загрузки </H1> <form name="form1" method="post" action="5_phpRedirect.php"> <input type="submit" name="button" value="0_elementsOfHTML"> </form> <form name="form2" method="post" action="5_phpRedirect.php"> <input type="submit" name="button" value="3_phpServer"> </form> </body> </html>
Скрипт-обработчик:
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title> Перенаправление пользователя </title> </head> <body> <?php $redirect = "Location: ". $_REQUEST["button"]. ".html"; echo header($redirect); ?> </body> </html>
Когда это бывает
Ошибка (предупреждение) типа:
Warning: Cannot modify header information - headers already sent by
Возникает, если вы уже сделали что-то что требует установки заголовков браузера, а теперь хотите переписать их новыми. Например, если вы уже вывели текст - то php выставляет заголовки (в частности заголовок Location -- которые показывает оставаться ли на запрошенной странице или же нужно нужно перейти на другую страницу и уже там получить ответ на запрос), чтобы показаться браузеру клиента (в своём ответе) как себя вести.
Корень проблемы
Скорее всего, проблема в вашем случае состоит в том, что вы уже отдаёте контент (html-тэги которые перемешаны в файле со скриптом) до команды:
echo header($redirect);
цитата:
Помните, что функцию header() можно вызывать только если клиенту еще не передавались данные. То есть она должна идти первой в выводе, перед ее вызовом не должно быть никаких HTML тэгов, пустых строк и т.п. Довольно часто возникает ошибка, когда при чтении кода файловыми функциями, вроде include или require, в этом коде попадаются пробелы или пустые строки, которые выводятся до вызова header(). Те же проблемы могут возникать и при использовании одиночного PHP/HTML файла.
-- то есть необходимо избавить скрипт-обработчик от html -- ведь он по сути сам ничего не выводит а просто перебрасывает на другой адрес -- это первое.
Далее, на самом деле заголовок Location следует менять так:
header($redirect);
А не так:
echo header($redirect);
Эксперимент
Так как echo() вообще-то пишет в тело http ответа, а не в заголовки, а header возвращается void (то есть не возвращает значений), о чём было сказано выше, то смысла в использовании echo() нет, но
-- тем не менее, предлагаю провести эксперимент:
- уберите html
- не убирайте echo
-- так как header() вызывается у вас по сути до echo() (так как header() является аргументом echo()) а значит возврат -- заодно проверим если функция возвращает null -- будет ли это интерпретироваться как пустая строка или же (что вернее) echo даже не начнёт работать как уже произойдёт редирект.
Ещё раз уточним причину
Т.е. перед вызовом header() не должен выводиться никакой контент ( о чем написано к описанию функции: http://php.net/manual/ru/function.header...)
То есть:
- 1) ни с помощью echo
- 2) ни с помощью обычного вываливания в браузер html-текста.
В нашем случае судя по всему echo не влияет ни на что, а вот html в обработчике очень даже влияет.
- Log in to post comments
- 14707 reads
melisa
Thu, 05/04/2017 - 14:00
Permalink
вопрос решился
По Вашему совету были удалены теги HTML. Теперь переадресация происходит корректно, скрипт-обработчик выглядит так:
Функция echo действительно не влияет на работу, т.е . можно оставить и как у С. Хольцнера:
Также при оформлении кода для редиректа следует обратить внимание на расширение файла, на который производится переход: при предложенном синтаксисе, оно должно быть указано в аргументе header.
math2
Thu, 05/04/2017 - 14:21
Permalink
Но можно заставить работать и
Но можно заставить работать и предыдущий обработчик
если выставить в файле php.ini опцию
vedro-compota
Thu, 05/04/2017 - 14:32
Permalink
насчёт буферизации
Вот тут хорошо объяснён механизм работы:
-- то есть когда выставлен ненулевой размер буфера, то пока он не заполнится ещё есть возможность манипулировать заголовками. При нулевом же размере буфера, после вывода контента, его отдача сразу же предваряется передачей клиенту заголовков http-ответа.
И получается, что мы хотим изменить заголовки, которые уже "улетели" по сети клиенту (а значит, исправить их уже невозможно -- в частности заголовок Location, который указывает оставаться ли на запрошенной странице, или запросить другую -- ответ скрипта-"перенаправителя" (у нас это обработчик формы) как раз говорит о том, что надо запросить другую страницу), о чем php нас и предупреждает.
Но: решать проблему таким способом конечно нельзя (не сильно корректно, точнее).
_____________
матфак вгу и остальная классика =)