Перенаправление заголовка PHP не работает при публикации формы - с использованием выходного буфера - но работает ли в других случаях? - PullRequest
1 голос
/ 28 апреля 2009

У меня необычная проблема, происходящая только на одном сервере. Следующий код

....
elseif ($_GET['action']=='login') {

 if (empty($_POST['login_name'])) { $_POST['login_name']=''; }
 if (empty($_POST['login_pass'])) { $_POST['login_pass']=''; }
 if (!empty($_POST['send'])) {
  if (($_POST['login_name']==_ADMIN_NAME) and    ($_POST['login_pass']==_ADMIN_PASS)) {
   //Successfully logged in
   $_SESSION['logged']=1;

// DOES NOT WORK
   header('Location: '.$filename);
   die('Command '.$filename);
  }
 }
// Show Form;
include('plogin.inc.php');
} 
elseif ($_GET['action']=='logout') {
 $_SESSION['logged']=-1;
// DOES WORK!
 header('Location: '.$filename);
}

Так что проблема в том, что если я нажму на ссылку выхода из системы, все пройдет хорошо, и я перенаправлюсь на $ filename. Если я отправляю форму входа в систему, она проверяет правильность сообщения, устанавливает переменную сеанса, но затем умирает вместо перенаправления.

У меня есть выходные буферы, все отчеты об ошибках, но (без ошибок), они не перенаправляются, когда я публикую с формой, даже если она определенно проходит (потому что переменная сеанса установлена, и я получаю часть die)

Что может быть причиной такого поведения? Спасибо

Ответы [ 7 ]

3 голосов
/ 28 апреля 2009

Я также обнаружил, что редирект иногда не работает после запроса POST. Это браузер, а не проблема на стороне сервера, я думаю.

Я использую что-то вроде этого:

if( sizeof( $_POST ) == 0 ) header( "Location: " . $url );
else echo '<html><head><meta http-equiv="refresh" content="1;url=' . $url . '"/></head><body>Redirecting to ' . $url . '</body></html>'

Короче говоря, если это запрос POST - тогда я использую html refresh redirect, иначе - обычное перенаправление заголовка.

2 голосов
/ 28 апреля 2009

Вы проверяли, что a) достигнут код и b) действительно ли действует сообщение об ошибке?

//Successfully logged in
$_SESSION['logged']=1;<br>
// code reached, error_reporting test
echo 'debug: would send location header', $filename, $unsetVariableTriggeringWarning;
flush();<br>
if (headers_sent()) {
  die('cannot send location header (anymore)');
}
else {
  header('Location: '.$filename);
  die();
}
1 голос
/ 12 января 2011

Когда вы отправляете перенаправление, PHP помещает значения в заголовок HTTP-ответа. Тело следует за заголовком. Поэтому, если вы выводите / выводите какое-либо значение перед использованием функции заголовка, оно завершается неудачей, поскольку заголовки ответа уже отсутствуют. Попробуйте тот же сценарий перед печатью любого текста, и он будет работать.

Нормальный HTTP-ответ

HTTP / 1.1 200 OK Дата: среда, 12 января 2011 18:40:22 GMT Сервер: Apache / 2.2.17 (Unix) mod_ssl / 2.2.17 OpenSSL / 0.9.8e-fips-rhel5 mod_auth_passthrough / 2.1 mod_bwlimited / 1.4 FrontPage / 5.0.2.2635 X-Powered-By: PHP / 5.2.14 Истекает: четверг, 19 ноября 1981 года, 08:52:00 по Гринвичу Cache-Control: нет хранилища, нет кэша, необходимо повторно проверить, пост-проверка = 0, предварительная проверка = 0 Прагма: без кеша Keep-Alive: тайм-аут = 5, максимум = 100 Подключение: Keep-Alive Передача-кодировка: чанки Тип контента: текст / html

[Тело сообщения]

HTTP / 1.1 302 Найдено Дата: среда, 12 января 2011 18:40:22 GMT Сервер: Apache / 2.2.17 (Unix) mod_ssl / 2.2.17 OpenSSL / 0.9.8e-fips-rhel5 mod_auth_passthrough / 2.1 mod_bwlimited / 1.4 FrontPage / 5.0.2.2635 X-Powered-By: PHP / 5.2.14 Расположение: profile.php Тип контента: текст / html

1 голос
/ 28 апреля 2009

Линия с

die('Command '.$filename);

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

Если вы используете достаточно новый PHP (> = 4.3.0 iirc), вы можете использовать целые числа 0..255 для обозначения условий выхода (если хотите), которые не будут напечатаны.

1 голос
/ 28 апреля 2009

может быть простой вещью. Функция header () устанавливает заголовок, но не завершает сценарий, поэтому заголовок отправляется сразу после вызова header ().

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

header('Location: '.$filename);
ob_end_flush();
exit();

С уважением, Mario

0 голосов
/ 28 февраля 2011
   header('Location: '.$filename);
flush(); //Try to force server to send header before script die
   die('Command '.$filename);

У меня была такая же проблема: сценарий: заголовок ('Location: ...'); умереть ();

Скрипт перед отправкой заголовков получил некоторые данные через POST, и если данные новые, внесите изменения в БД. Любопытно, что когда POST-данные небольшие и мало меняются, БД перенаправляют РАБОТУ, когда POST-данные больше и много изменений в БД перенаправляют НЕ РАБОТАЮТ Использование flush () после header () решает мою проблему.

PHP Версия 5.2.17 Apache / 2.2.3 (CentOS)

На мой взгляд, похоже, что push-заголовки сервера буферизуются и умирают перед отправкой содержимого буфера пользователю, и именно поэтому flush () помог.

Если очистка не работает, см. Комментарии о настройках буферизации вывода и zlib.compression: http://ru2.php.net/manual/en/function.flush.php

0 голосов
/ 28 апреля 2009

По моему опыту, вы не можете отправлять контент, когда делаете переадресацию. Поэтому я думаю, что ваша проблема в параметре die ().

Я не могу найти это в документации прямо сейчас, но попробуйте умирать () без параметра или просто использовать exit; Могу поспорить, это будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...