Как избежать повторной отправки данных при обновлении в php

У меня есть страница index.php, где у меня есть ссылка с именем "add_users.php". В "add_users.php" я принимаю данные пользователя и возвращаюсь к той же странице "index.php", где информация поступает через пост-действие и вставляется в базу данных.

Когда я обновляю страницу или нажимаю кнопку "Назад", появляется окно повторной отправки. Я прошел через множество решений, где они попросили меня создать третью страницу. Я попытался сделать это следующим образом: после вставки значений в базу данных я перенаправил страницу как заголовок ( "Местоположение: http://thisisawebsite.com/thankyou.php, и в благодарность .php Я снова перенаправил страницу на index.php. Но это привело к появлению предупреждения как" Невозможно изменить информацию заголовка - заголовки, уже отправленные [....]"

Какое лучшее решение?

Ответ 1

Пожалуйста, используйте ob_start(); в самой строке.

Ответ 2

Приянка,

Вы на правильном пути. То, что вы пытаетесь реализовать, на самом деле является хорошо известным шаблоном, используемым в веб-разработке, называемым шаблоном POST/Redirect/GET. (Шаблоны - это немного слова с громким голосом сейчас, поэтому, возможно, парадигма - лучшее слово для этого).

Общая реализация этого шаблона/парадигмы состоит в том, чтобы просто иметь только одну точку ввода.

Таким образом, add_user.php теперь может выглядеть так (это еще не самый элегантный, но, надеюсь, это даст вам представление о том, как его реализовать):

<?php

// is this a post request?
if( !empty( $_POST ) )
{
   /*
     process the form submission
     and on success (a boolean value which you would put in $success), do a redirect
   */
   if( $success )
   {
       header( 'HTTP/1.1 303 See Other' );
       header( 'Location: http://www.example.com/add_user.php?message=success' );
       exit();
   }
   /* 
      if not successful, simply fall through here
   */
}

// has the form submission succeeded? then only show the thank you message
if( isset( $_GET[ 'message' ] ) && $_GET[ 'message' ] == 'success' )
{
?>

<h2>Thank you</h2>
<p>
You details have been submitted succesfully.
</p>

<?php
}
// else show the form, either a clean one or with possible error messages
else
{
?>

<!-- here you would put the html of the form, either a clean one or with possible error messages -->

<?php
}
?>

Итак, как это работает в основном:

  • Если запрос, сделанный в script, не является запросом POST (т.е. форма не была отправлена), и нет добавленного ?message=success к URL-адресу, просто покажите чистую форму.
  • Если запрос, сделанный в script, является POST-запросом, обработайте форму.
    • Если обработка формы прошла успешно, снова перенаправляйтесь к тому же script и добавьте ?message=success
      • Если запрос к script является запросом с ?message=success, добавленным к нему, только покажите сообщение благодарности, не показывайте форму.
    • Если обработка формы завершилась неудачно, пусть она "провалится" и снова отобразит форму, но на этот раз с некоторыми описательными сообщениями об ошибке и с элементами формы, заполненными тем, что пользователь уже заполнил.

Надеюсь, это, наряду с примером, который я вам дал, имеет достаточный смысл.

Теперь причина, по которой вы получили печально известное сообщение Warning: headers already sent, объясняется в этом ответе, которое я дал, на другой вопрос о том, почему некоторые php-вызовы лучше использовать вершина script (на самом деле, она не обязательно должна быть сверху, но она должна быть вызвана до выхода ANY (даже случайного) пробела).

Ответ 3

Но получение предупреждения как нельзя изменить информацию заголовка - уже отправленные заголовки

Что-то не так с использованием буферизации вывода? Почему ваша страница отправляет заголовки, даже если она работает только в базе данных? У вас есть пробел или новая линия перед первым "

У вас есть решение, вы должны просто заставить его работать.

Ответ 4

Я думаю, что использование сеансов - лучший способ предотвратить эту проблему.

session_start();
if(!isset($_SESSION['s'])){
  $_SESSION['s'] = true;
};

if( !empty( $_POST ) && ($_SESSION['s']) )
{
  //your code
 $_SESSION['s'] = false;
}

Впоследствии вы можете использовать unset($_SESSION['s']) или destroy_session(), если вы хотите, чтобы пользователи могли публиковать что-то снова.

Ответ 5

Тот же вызов, с которым я столкнулся, используя поле комментариев, я сделал, чтобы перенаправить страницу на ту же страницу и на конкретный "якорь". Пример:

<form id="myForm" action="<?php echo $_SERVER['PHP_SELF'];?>#myForm" method="post">
<!--Stuff for form in here -->
</form>

Тогда для кода PHP у меня есть:

<?php

//Do your stuff and when finished...

$reloadpage = $_SERVER['PHP_SELF']."#myForm";
header("Location:$reloadpage");
exit();

?>

Это позволяет избежать повторной отправки F5 данных из формы

Ответ 6

Используйте meta refresh

<% meta http-equiv = "refresh" content = "5; url = http://example.com/" / " > " на время вашего успешного сообщения после добавления данных в БД.

может быть его трюком, чтобы избежать перезагрузки.

Thanxs, Гоби.

Ответ 7

Используйте этот

window.location.href= 'название вашей страницы'