Добавил данные через форму один раз, а в базе обнаружил 500 записей с этими даннымн

karen12

Постоялец
Регистрация
26 Фев 2012
Сообщения
108
Реакции
4
Здравствуйте, у меня в клинике уже три года стоит веб программка, через которую я записываю приемы своих пациентов. Программу написал я сам. Все эти 3 года программа работала нормально, но сегодня , когда я добавил очередного пациента, обнаружил, что в базе этот самый пациент добавился 500 раз, с разными ID, но одинаковыми временами добавления, вплоть до секунды. В чем может быть проблема, и как защитися от таких ошибок.?

Код:
<?
if($action == "add") {
mysql_query(

"INSERT INTO
`send` (
`hert_id`,
`date_inccome`,

  `ds_in`,
`depart_in`,
`subdepart_in`,
`hyst_dep`,
`doctor_in`,
`status`
)

VALUES
(
'{$hert_id}',
'{$date_inccome}',
'{$ds_income}',
'{$depart_in}',
'{$subdepart_in}',
'{$hyst_dep}',
'{$doctor_in}',
'{$status}'
)"

) or die(mysql_error());
header ("Location: nurse_reception.php#win1");
}
?>
 
Можно как в ВКонтакте при отправке сообщения. Там в форме есть случайное число, после отправки оно меняется. Если тыкать кнопку - на сервер отправится несколько запросов с одним сообщением и одним случайным числом. Именно по случайному числу вк отсеет лишние сообщения, а запишет только 1.

С такой системой ты можешь одинаковое сообщение отправлять хоть 100 раз - будет 100 сообщений, а если 100 раз просто по кнопке тыкнешь быстро - будет 1 сообщение.

В базе сохраняешь это число. В качестве такого числа можно использовать php функцию time()

1. В форму добавить: <input type="hidden" name="number" value="<?php echo time(); ?>" />
2. В бд добавить уникальное поле.
ALTER TABLE send ADD number INT(10) UNSIGNED;
ALTER TABLE send ADD UNIQUE KEY (`number`);
3. В запросе заменить INSERT INTO на INSERT INGORE INTO

После отправки формы число должно меняться. Но это сработает если только 1 пользователь, так как могут 2 человека одновременно форму открыть и запись добавится только 1 того, что первый форму отправит. Тогда надо делать уникальный ключ на 2 поля, number и account_id
 
Можно как в ВКонтакте при отправке сообщения. Там в форме есть случайное число, после отправки оно меняется. Если тыкать кнопку - на сервер отправится несколько запросов с одним сообщением и одним случайным числом. Именно по случайному числу вк отсеет лишние сообщения, а запишет только 1.

С такой системой ты можешь одинаковое сообщение отправлять хоть 100 раз - будет 100 сообщений, а если 100 раз просто по кнопке тыкнешь быстро - будет 1 сообщение.

В базе сохраняешь это число. В качестве такого числа можно использовать php функцию time()

1. В форму добавить: <input type="hidden" name="number" value="<?php echo time(); ?>" />
2. В бд добавить уникальное поле.
ALTER TABLE send ADD number INT(10) UNSIGNED;
ALTER TABLE send ADD UNIQUE KEY (`number`);
3. В запросе заменить INSERT INTO на INSERT INGORE INTO

После отправки формы число должно меняться. Но это сработает если только 1 пользователь, так как могут 2 человека одновременно форму открыть и запись добавится только 1 того, что первый форму отправит. Тогда надо делать уникальный ключ на 2 поля, number и account_id

но ведь там у меня после запроса к базе стоит
header ("Location: nurse_reception.php#win1");, то есть если один раз данные пошли, происходить переадресация. В таком случае, как туда попали в место 1 -ого записа 500?
 
Последнее редактирование:
Если интернет медленный, то запросы отправятся, а ответ будет через какое-то время. За это время можно и 500 раз отправить форму
 
Если интернет медленный, то запросы отправятся, а ответ будет через какое-то время. За это время можно и 500 раз отправить форму
Логика понятна! Сделал так как Вы сказали. Надеюсь это зашитит от подобных случаев.
 
Я защищался от повторной отправки формы похожим методом, только при формировании формы в сессию записывал случайное число и дублировал его же в поле HIDDEN
Если числа не совпадали, данные из формы не применял и выводил сообщение о том, что "значения формы устарели"
 
Я защищался от повторной отправки формы похожим методом, только при формировании формы в сессию записывал случайное число и дублировал его же в поле HIDDEN
Если числа не совпадали, данные из формы не применял и выводил сообщение о том, что "значения формы устарели"
В чем преимущество данного метода от того что предложил Для просмотра ссылки Войди или Зарегистрируйся ?.
 
В чем преимущество данного метода от того что предложил Для просмотра ссылки Войди или Зарегистрируйся ?.
1. Если два пользователя с разных браузеров одновременно заполнят форму, то в его методе будет одна запись, в моем - две
2. Его метод чуть проще в реализации
 
После отправки формы число должно меняться. Но это сработает если только 1 пользователь, так как могут 2 человека одновременно форму открыть и запись добавится только 1 того, что первый форму отправит. Тогда надо делать уникальный ключ на 2 поля, number и account_id
Сделал так как Вы сказали с двумя уникальными полями, но все равно проходит только одна запись, независимо от значения account_id. Как можно исправить, чтобы данный фильтр работал только для данного account_id (то есть фильтровались повторные запросы с одного account_id)
 
Код не проверял, просто для понимания
PHP:
session_start();
if (isset($_SESSION['hidden_code']) and $_SESSION['hidden_code'] == $_GET['hidden_code']) {
// вставка
// редирект
} else {
$_SESSION['hidden_code'] = rand();
// вывод формы <input type='hidden' name='hidden_code' value='<?=$_SESSION['hidden_code'];?>'>
}
 
Назад
Сверху