Всем привет. Я новичок в php. Но вопрос задаю здесь, в теме для начинающих на него вряд ли ответят. Есть небольшое приложение на php, которое работает с базой MySql. Около 20 пользователей со смартфонов, планшетов, десктопов, до 10 транзакций на каждого пользователя в день, соответственно в месяц выходит всего до 5 тысяч транзакций. Пользователь находит клиента и открывает таблицу со всеми транзакциями выбранного клиента. Нажимает добавить и запускается скрипт, одностраничная форма для ввода данных. Пользователь вводит нужные поля, ставит чекбоксы и нажимает сохранить. По сабмиту открывается транзакция, пишутся данные, завершается транзакция, делается редирект на предыдущую страницу, после редиректа стоит exit(). И все работает, но на 5 тысяч транзакций получается несколько дублей. Один пользователь точно запомнил, что он нажал сохранить и браузер или смартфон завис, а потом он увидел дважды введенную транзакцию. Как локализовать и с чем это связано - не знаю. Что делать? Могу сделать проверку на существование точь такой транзакции и не писать. Но хотелось бы понять откуда берутся дубли. Куда копать? Спасибо
Для начала прочитать что такое транзакции. В Вашем случае это просто записи в бд, а не транзакции. Делать проверку на отправку данных клиентом не чаще чем например пары секунд. А так типа нажать можно умудрился несколько раз сабмит до того как форма исчезнет
Твитур, до кучи, проверяет содержимое поста. Возможно, считает хэш сообщений и сверяет его. Мессаги у них короткие, они могут это себе позволить. Если послать два одинаковых сообщения с малым интервалом, он пишет, мол "ой, кажется вы это уже писали".
Нет, в моем случае именно транзакции. Типа Код (Text): if(!empty($_POST["addrecord"])) { // сабмит Здесь подготовка mysqli_begin_transaction($connection, MYSQLI_TRANS_START_READ_WRITE); Здесь INSERT, UPDATE if ($ErrorFlag == 0) { mysqli_commit($connection); $NewLocation = "mytable.php?id=" . $_SESSION["id"]; redirect_to($NewLocation); exit (); } else { mysqli_rollback($connection); $entry = 'id = ' . $_SESSION["id"] . ' Rollback при записи ' . $_SESSION["grp_name"]; write_to_log($entry); $NewLocation = "mytable.php?id=" . $_SESSION["id"]; redirect_to($NewLocation); exit(); } } Что значит нажать несколько раз сабмит пока форма исчезнет? Как я понимаю, после нажатия сабмит идет выполнение необходимого кода и уход на другую страницу. И массив пост перестает существовать, точнее на новой странице он другой.
При нажатии на сабмит идёт запрос пост или гет по определенному адресу указанному в экшене, отработка сценария. Если плохая связь или сервер тупит - до момента пока прийдёт ответ от сервера, можно успеть ещё раз отправить запрос, та как содержимое экрана ещё все то же - с формой. Особенно если плохой канал связи и оператор быстро шлёпает данные. Проверка на допустимый интервал обычно спасает
А разве уход на другую страницу и exit() не помогают? Да, проблема проявлялась при зависании браузера из-за мобильного интернета.
повторная отправка происходит ДО того как сервер отработал и выдал что-то другое на экран, если быть ловким - и плохой инет - можно и 3-4 раза отправить Перед записью - находите последнюю запись данного пользователя - проверяете разницу между ней и текущим временем - если меньше 2 сек например - явно дубль
По специфике работы не может быть в один день и в одно время одинаковых записей у одного пользователя. То есть можно просто проверять на существование записи. P.S. А можно перед вызовом скрипта с формой обнулять поле флага в сессии, а при записи проверять флаг, если null - сохраняем значение флага в сессии и пишем данные в базу иначе выход?
Это уже я понял, пока нет ответа от сервера, то можно добавить и дубль. А если перед вызовом скрипта с формой обнулять поле флага в сессии, а при записи проверять флаг, если null - сохраняем значение флага в сессии и пишем данные в базу иначе выход?
А что мешает повесить на форму событие onsubmit, в котором "поднимать флаг" о том, что отправка данных уже происходит. Ещё раз жмем отправку, а облом - флаг уже поднят. Немножко скрипта должно скрасить обстановку)
Хотя почему будет дубль? Пусть скрипт не получил ответ от сервера и будет выполнен второй раз. Первый раз добавится запись в базу, а во второй раз нет. --- Добавлено --- Мешает незнание JS.
Как-то так: Код (Text): <form onsubmit="send(this); return false"> ... </form> <script> var inProgress = false; function send(f) { if (!inProgress) { inProgress = true; f.submit(); } } </script>
Спасибо. А то я не веб-программист. Как решить задачу для меня не проблема, но хотелось бы это сделать правильно, как для веб-программирования, а не обходными путями. А осваивать JS все равно придется. У заказчика аппетит пришел во время еды. Он все больше функций хочет переложить на пользователей со смартфонами и планшетами.
Да я вообще делфист)) Увлекся с 10-ку лет назад php, js, jquery, css, etc. После строгого Делфи просто тащусь. --- Добавлено --- Ах да, для "спасибо" существует кнопочка)
минус решения на js - если js будет отключен пользователем... (хотя щас такое редкость) ну и если это некое АПИ для моб приложения - там тоже может и не быть js и формы как таковой
Ну так обязать пользователей данного продукта не отключать js, тем более этот проект не для широких масс. Или, как вариант для андроид-устройств, скачать Android Studio, написать простейший проект с формой, на которую кинуть браузер, настроенный на адрес с проектом. Открыл приложение - попал на страничку, запостил инфу на сервер. Вариант посложнее: все та же Android Studio, форма с компонентами, чекбоксами для ввода инфы, нажали "отправить" и данные через http-компонент улетели на сервер. Только в этих случаях, особенно во втором, придется заняться изучением джавы) Можно пойти еще дальше и установить тот же Embarcadero Delphi XE10 Berlin, написать проект, скомпилировать его под разные платформы (windows mobile, android, ios) для пользователей с разными операционными системами и девайсами. Вот только придется изучать еще один язык программирования, причем не самый легкий. Либо не мучать головной мозг и пятую точку, а просто включить js))