Довольно часто встречается проблема ” повторной отправки формы в php
“. На самом деле – ” отключить повторную отправку формы в php
” очень просто! Рассмотрим это с примерами.
Вопрос решил похожим способом, как указанный вверху.
Первым делом
в шапке оставил только это
<?php
include_once 'functions.php';//подключаю функции
ob_start();//буферизация начата
?>
$full_article = showArticle();//функция получает из базы данных всю информацию о статье
перенес сверху непосредственно, в то место, где начинается
foreach ($full_article as $full_art){...}
$article_comments = selectArticleComments();
перенес туда, где начинается
foreach ($article_comments as $article_comment){...}
затем во всех подключаемых файлах вроде header, sidebar и т.д. удалил ненужные include(потому что хедер и аналогичные элементы подключаются в index.php или article.php. таким образом избежал ненужных повторов) я новичок в этом, потому подключать файлы везде где только можно я люблю)))
В самом низу документа код
<?php
if (isset($_POST['do_post'])){
addComment();//добавление комментария в БД
header("Location: " . $_SERVER['HTTP_REFERER']);//возвращаем пользователя на ту же страницу(поскольку она имеет вид не просто article.php а article.php?id=4 т.е. в зависимости от id статьи. адрес меняется)
}
P. S.
данный способ работает. Возможно он не идеален, но я лишь учусь. Всем огромное спасибо за помощь. Возможно кому-то тоже это поможет.
Самый простой и правильный, на мой взгляд, вариант, это разнести по разным файлам, отделить html от php кода.
Например:
index.php будет содержать:
<!DOCtype html>
<html>
<head>
<title>Запись в БД через форму на php</title>
</head>
<body>
<?php
require_once 'form.php';
require_once 'list.php';
?>
</body>
<form method="POST" action="send.php" >
<label>От кого: </label><br>
<input name="name" type="text" value="" placeholder="Имя"/><br>
<label>Сообщение: </label><br>
<textarea name="text" type="text" cols="30" rows="20" placeholder="Текст"/></textarea>
<input type="submit" value="Отправить"/>
<?php
//Тут необходимо прописать параметры подключения к БД
//А лучше их вынести в отдельное место, например создать config.php
$result = mysqli_query($mysqli, "SELECT * FROM `mytable`");
while($r1 = mysqli_fetch_assoc($result))
{
echo 'Имя: '.$r1['name'].'<br>'.'Сообщение: '.$r1['text'];
echo '<hr>';
}
if (isset($_POST['name']) && isset($_POST['text'])){
// Переменные с формы
$name = $_POST['name'];
$text = $_POST['text'];
$_SESSION["name"]= $name;
$_SESSION["text"]= $text;
// Параметры для подключения
$db_host = "localhost";
$db_user = "root"; // Логин БД
$db_password = ""; // Пароль БД
$db_base = "sega"; // Имя БД
$db_table = "mytable"; // Имя Таблицы БД
// Подключение к базе данных
$mysqli = new mysqli($db_host,$db_user,$db_password,$db_base);
$mysqli->query("SET NAMES 'utf8'");
$mysqli->query (
"CREATE TABLE `sega`.`mytable`(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR,
`text` VARCHAR(255),
`regdate` DATE
)
");
$errors = array();
if( $_POST['name'] == '' ) {
$errors[] = 'Введите Ваше имя!';
}
if( $_POST['text'] == '' ) {
$errors[] = 'Введите Ваш текст!';
}
if ( empty($errors) ) {
$result = $mysqli->query("INSERT INTO ".$db_table." (name,text) VALUES ('$name', '$text')");
}else {
//Errors are present
echo $errors['0'] . '<hr><br>';
}
в файле send.php, после успешной записи в базу, добавьте редирект на index.php. P.S. Код, который я привел, не проверял на наличие логических и синтаксических ошибок, писал на скорую руку, только для того, чтоб чуть моей мысли была более понятной:)
Отмена повторной отправки формы
Мне часто задают вопросы относительно отмены повторной отправки формы
. Например, Вы сделали форму добавления комментария, добавили обработчик на эту же страницу. Затем при добавлении комментария он успешно добавляется, но стоит пользователю нажать F5
, как форма будет отправлена ещё раз
. А F5
пользователь может легко нажать, если страница будет долго грузиться. В итоге, вместо 1-го
комментария будет целых 2
, а то и больше. В этой статье я покажу, как этого можно избежать.
Для начала разберём более подробно проблему на примере этого кода:
<?php
if (!empty($_POST["sqr"])) {
echo "Квадрат числа ".$_POST["x"]." равен ".pow($_POST["x"], 2);
}
?>
<form name="form" action="" method="post">
<div>
<input type="text" name="x" />
<br />
<input type="submit" value="Возвести в квадрат" name="sqr" />
</div>
</form>
Нажав на кнопку ” Возвести в квадрат
“, Вы увидите результат работы скрипта. Но стоит после этого пользователю нажать F5
, как скрипт снова будет выполняться. В данном случае, это не так критично, как с добавлением комментарием, однако, зачем нужна лишняя нагрузка на сервер?
Теперь поговорим о способах решения данной проблемы. Первый способ – выделить скрипт обработки в отдельный файл
. Тогда в атрибуте action
у тега form
надо добавить путь к этому скрипту. А сам скрипт должен сохранять куда-нибудь результат своих действий, либо переменные пришедшие на скрипт, а после делать редирект обратно. В общем, смотрите код скрипта:
<?php
session_start();
$_SESSION["x"] = $_POST["x"];
header("Location: ".$_SERVER["HTTP_REFERER"]);
exit;
?>
А код страницы с формой теперь будет выглядеть так:
<?php
session_start();
if (isset($_SESSION["x"])) echo "Квадрат числа ".$_SESSION["x"]." равен ".pow($_SESSION["x"], 2);
}
?>
<form name="form" action="request.php" method="post">
<div>
<input type="text" name="x" />
<br />
<input type="submit" value="Возвести в квадрат" name="sqr" />
</div>
</form>
Недостаток этого подхода очевиден – приходится создавать ещё один файл для такого простого скрипта. Поэтому рассказываю и про второй способ
, как можно избежать повторной отправки формы
:
<?php
session_start();
if (!empty($_POST["sqr"])) {
$_SESSION["x"] = $_POST["x"];
header("Location: ".$_SERVER["REQUEST_URI"]);
exit;
}
if (isset($_SESSION["x"])) echo "Квадрат числа ".$_SESSION["x"]." равен ".pow($_SESSION["x"], 2);
?>
<form name="form" action="" method="post">
<div>
<input type="text" name="x" />
<br />
<input type="submit" value="Возвести в квадрат" name="sqr" />
</div>
</form>
Здесь обработка снова происходит в этом же файле, но ключевое отличие – это наличие редиректа на эту же страницу в конце
. В результате, страница перегрузится после отправки формы и браузер при нажатии F5
не будет предлагать пользователю отправить форму ещё раз.
Подведу итог того, как отменить повторную отправку формы
:
- Либо делать обработку в отдельном файле
, а затем оттуда делать редирект назад. - Либо делать обработку в том же файле, что и форма, но при этом после обработки делать редирект на ту же страницу
.
Вот так это делается в простых скриптах. Да и, в сложных, в конечном счёте делается то же самое.
Создано 04.11.2013 21:55:05
-
Михаил Русаков
Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт ( http://myrusakov.ru
)!
Добавляйтесь ко мне в друзья ВКонтакте
: http://vk.com/myrusakov
.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy
.
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
- Кнопка:
Она выглядит вот так:
- Текстовая ссылка:
Она выглядит вот так: Как создать свой сайт
- BB-код ссылки для форумов (например, можете поставить её в подписи):
Дело в том, что после отправки пост запроса скрипт принимает отправленные данные, проверяет их на корректность (валидность, заполненность обязательных данных и т.д.) и выдает ответ – либо операция прошла успешно, либо произошла ошибка и список ошибок (например: ошибка — поле «имя» не заполнено. А на странице отправки уже в свою очередь выдается соответствующее сообщение: отправка успешна или не успешна.
Так вот есть ли элегантный вариант предотвратить повторную отправку формы?
Например мне пришла идея что если в javascript поймать событие обновления страницы(если такова есть отменить её и просто сделать переход по текущей ссылке.
Или если можно на сервере после получении данных POST запроса удалить какие нибудь информацию о запросе может она не будет повторно отправляться так как данные удалены?
А еще редирект не вариант. Так как после редиректа я не могу передать ответ скрипта.
А еще махинации с дополнительным полем с уникальным значением сохраненным на сессии и дальнейшая их проверка тоже крайний вариант.
Что скажете есть какие нибудь варианты?
задан 11 июл 2016 в 15:17
Shuhratjon Jumaev
1 золотой знак
6 серебряных знаков
23 бронзовых знака
Чтобы было понятно, это вопрос уровня таблицы умножения в веб-программировании. И размышления вида “делать редирект или не делать” это все равно как если бы рассуждать “дважды два равное четыре не вариант. мне нужно пять”.
После POST запроса всегда должен быть редирект. Точка. Переходим к делению в столбик.
А еще редирект не вариант. Так как после редиректа я не могу передать ответ скрипта.
Ответ, если очень хочется его передать, пишется в сессию, и после редиректа оттуда показывается.
Впрочем, на большинстве современных сайтов (включая и этот) отправка формы осуществляется с помощью технологии AJAX, которая не требует перезагрузки страницы.
ответ дан 11 июл 2016 в 15:25
3 золотых знака
27 серебряных знаков
49 бронзовых знаков
Если вам нужно точно узнать приймет ли сервер данные клиента – пробуйте сабмитить через Ajax, – если правильно сохраняете и переводите куда нужно. Если не удачный запрос – сразу можно показать клиенту корректную ошибку.
например что то типа
var jqxhr = $.post("example.php")
.success(function() { alert("Успешное выполнение"); })
.error(function() { alert("Ошибка выполнения"); })
.complete(function() { alert("Завершение выполнения"); });
в коллбеках нужно получить нужную информацию которая пришла из сервера.
Тоесть ответ – не сабмитить форму на прямую а отсылать через асинхронно через Аякс. – Данные не будут отпарвляться повторно при перезагрузке
ответ дан 11 июл 2016 в 15:32
Решением вопроса была запись ошибок в сессии, после редирект и после вывод ошибок из сессии и сразу удалить ее.
Так как я использую codeigniter в коде решения будет использован codeigniter но думаю суть будет ясна всем.
Пример записи ошибки:
$phone_number = $this->input->post('phone_number');
if (is_numeric($phone_number) && strlen($phone_number) == 9 && (int)$phone_number > 100000000) $value = $phone_number;
else {
$this->session->set_userdata('msg', array('ok' => 0, 'msg' => "Неверный формат номера телефона.<br>Номер должен указываться без пробелов, знаков тире или других знаков.<br>Например: 987654321", 'type' => "warning"));
redirect('/user/config');
}
Пример ловля, вывода и удаления ошибки из сессии:
if ($this->session->has_userdata('msg')) {
$msg = $this->session->userdata('msg');
$this->session->unset_userdata('msg');
if (count($msg) && strlen($msg['msg']) > 0)
{
echo '<div class="alert alert-' .$msg['type'] .' alert-dismissible" role="alert" style="margin: 20px;"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>'.$msg['msg'].'</div>';
}
}
ответ дан 27 июл 2016 в 7:22
Shuhratjon Jumaev
1 золотой знак
6 серебряных знаков
23 бронзовых знака
На своём сайте я решил проблему заменой Location
при сохранении результата:
header('Location: ' . $url);
ответ дан 11 июл 2016 в 15:23
2 золотых знака
13 серебряных знаков
28 бронзовых знаков
header( "Refresh:5; url='#', true, 303);
покажет сообщение на 5 сек.
ответ дан 12 июл 2016 в 14:16
Убрать повторную отправку формы php.
С самого начала давайте обговорим “логику убирания повторной отправки формы”, а далее приступим к теории!
Пример повторной отправки формы
Давайте разберемся – как происходит повторная отправка формы в php. Для этого нам понадобится такая форма. чтобы мы смогли увидеть в реальности – повторную отправку формы!
Html + Php :
<form action=”#result” method=”post”>
<input type=”text” name=”example” value=”привет мир”>
<input type=”submit” value=”Нажми на меня” name=”submit”>
Разместим выше приведенный код прямо здесь:
Что нужно сделать!?
Нажмите кнопку “Нажми на меня”.
После перезагрузки страницы нажмите “F5”.
И далее вы должны получить вот такой результат:
Если вы нажмете “продолжить”, то первые данные отправятся второй раз на сервер.
Нам это не нужно!
Как избавиться от “повторной отправки формы!?”
Пример удаления удаления повторной отправки формы через action
Для того, чтобы “удалить повторную отправку формы через action” – введите :
В первое поле – первое число.
Во второе поле – второе число.
И нажмите кнопку – “Отключи повторную отправку”
Пример формы для отключения повторной отправки формы
Скачать – что в архиве?
В архиве приведенный пример теории:
Файл №1 с формой:
Вторая страница – полностью соответствует описанию
Бонус!
В двух файлах использована теория и практика вывода автоматически
определяемого пути.
Логика отключения повторной отправки формы №1
Обрабатываем post
на отдельной странице.
На данную страницу отправляем с помощью action
.
У нас есть такая вещь как сессия
– это будет контейнером для переноса полученного результата.
Соберем весь код отмены повторной отправки формы php
отключение запроса на повторную отправку формы,
на примере
Обращаю ваше внимание!
В связи с тем, что на данной странице – возникает ошибка “header” – что заголовки были уже отправлены!
на примере
Отключаем повторную отправку формы php
Чтобы отключить “повторную отправку формы php” нам придется немного изменить код, который мы написали ранее.
Чем отличается выше приведенный код(в предыдущем пункте).
Далее header + refresh – перезагрузка.
+ exit
, чтобы программа дальше не пошла.
При перезагрузке проверяем существует ли сессия:
“убрать повторную отправку формы”.
Для того, чтобы отключить повторную отправку формы Вам понадобится:
В тег помещаем action
с адресом(это живой пример) :
<form action="https://dwweb.ru/__a-data/__all_for_scripts/__examples/html/redirect.php" method="post" class="variant_action">
<input type="number" name="variant_action_1" required>
<input type="number" name="variant_action_2" required>
<input type="submit" value="Отключи повторную отправку" name="variant_action">
</form>
Добавим стили, чтобы наши ” input
“-ы выглядели чуть поинтереснее.
Как убрать окно «Подтвердите повторную отправку формы»?
На странице есть формы, которые обрабатываются на той же странице.
И в зависимости от отправленной формы, выводятся соответствующие данные.
Но при обновлении страницы, когда форма уже отправила данные, всплывает это окно, как его убрать без редиректа?
-
Вопрос заданболее трёх лет назад
5
комментариев
Никак. Что бы выводить в зависимости от отправленной формы соответствующие данные, сохраняйте их в файл или в сессию, и делайте редирект.
ДмитрийЭто арбузер шалит, после обработки и прочего, сделайте редирект на реферер
Дмитрий
, а если вылезает при возврате на предыдущую страницу?
Дмитрийaspirantes
, для этого и нужен редирект, чтоб очистить данные пост
Ответы на вопрос
Смените метод POST на GET.
Если я правильно понял вопрос, то чтобы не появлялось окно браузера когда форма уже заполнена данными (во избежания из потери и повторного ввода) нужно как-раз таки сделать редирект. Если данные нужны в полях, проще сохранить в сессию и после редиректа со страницы отображать в полях, при повторном очищать.
Используйте javascript, если идет взаимодействие с сервером, можно воспользоваться ajax.
Похожие вопросы
17 окт. 2023, в 09:22
1000 руб./за проект
17 окт. 2023, в 08:43
3000 руб./за проект
17 окт. 2023, в 08:41
3000 руб./за проект
Минуту внимания
Вторая страница.
Перейдем ко второй странице(который в действии). На ее ограничениям:
Проверим стартовала ли сессия
– располагаем в самом верху.
Примем два сообщение
с использованием Strip_tags
.
Сложим
их(у нас два числа – вы же можете оставить и принять любые посты).
Помещаем на сессию полученное значение.
Сделаем переадресацию
назад на эту страницу.
Далее убиваем
сессию.