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

Тема в разделе "Базы данных", создана пользователем karen12, 14 фев 2018.

Модераторы: latteo
  1. karen12

    karen12 Постоялец

    Регистр.:
    26 фев 2012
    Сообщения:
    102
    Симпатии:
    2
    Здравствуйте, у меня в клинике уже три года стоит веб программка, через которую я записываю приемы своих пациентов. Программу написал я сам. Все эти 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");
    }
    ?>
    
     
  2. Q_BASIC

    Q_BASIC

    Регистр.:
    30 ноя 2013
    Сообщения:
    446
    Симпатии:
    319
    Можно как в ВКонтакте при отправке сообщения. Там в форме есть случайное число, после отправки оно меняется. Если тыкать кнопку - на сервер отправится несколько запросов с одним сообщением и одним случайным числом. Именно по случайному числу вк отсеет лишние сообщения, а запишет только 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
     
    karen12 нравится это.
  3. karen12

    karen12 Постоялец

    Регистр.:
    26 фев 2012
    Сообщения:
    102
    Симпатии:
    2
    но ведь там у меня после запроса к базе стоит
    header ("Location: nurse_reception.php#win1");, то есть если один раз данные пошли, происходить переадресация. В таком случае, как туда попали в место 1 -ого записа 500?
     
    Последнее редактирование: 14 фев 2018
  4. Q_BASIC

    Q_BASIC

    Регистр.:
    30 ноя 2013
    Сообщения:
    446
    Симпатии:
    319
    Если интернет медленный, то запросы отправятся, а ответ будет через какое-то время. За это время можно и 500 раз отправить форму
     
    karen12 нравится это.
  5. karen12

    karen12 Постоялец

    Регистр.:
    26 фев 2012
    Сообщения:
    102
    Симпатии:
    2
    Логика понятна! Сделал так как Вы сказали. Надеюсь это зашитит от подобных случаев.
     
  6. Цуиьфыеук

    Цуиьфыеук Создатель

    Регистр.:
    15 янв 2018
    Сообщения:
    40
    Симпатии:
    16
    Я защищался от повторной отправки формы похожим методом, только при формировании формы в сессию записывал случайное число и дублировал его же в поле HIDDEN
    Если числа не совпадали, данные из формы не применял и выводил сообщение о том, что "значения формы устарели"
     
  7. karen12

    karen12 Постоялец

    Регистр.:
    26 фев 2012
    Сообщения:
    102
    Симпатии:
    2
    В чем преимущество данного метода от того что предложил Q_BASIC ?.
     
  8. Цуиьфыеук

    Цуиьфыеук Создатель

    Регистр.:
    15 янв 2018
    Сообщения:
    40
    Симпатии:
    16
    1. Если два пользователя с разных браузеров одновременно заполнят форму, то в его методе будет одна запись, в моем - две
    2. Его метод чуть проще в реализации
     
  9. karen12

    karen12 Постоялец

    Регистр.:
    26 фев 2012
    Сообщения:
    102
    Симпатии:
    2
    Сделал так как Вы сказали с двумя уникальными полями, но все равно проходит только одна запись, независимо от значения account_id. Как можно исправить, чтобы данный фильтр работал только для данного account_id (то есть фильтровались повторные запросы с одного account_id)
     
  10. Цуиьфыеук

    Цуиьфыеук Создатель

    Регистр.:
    15 янв 2018
    Сообщения:
    40
    Симпатии:
    16
    Код не проверял, просто для понимания
    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'];?>'>
    }