| | Vladsvn 
 Member
 | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору 
 Цитата:
 Тест длинный. Иногда человек на часть вопросов отвечает сегодня, а на остальные на следующий день, продолжая с этого же места. Хранение в базе позволяет это сделать.| и чем это плохо? можно ограничить время жизни сессии, чтобы нельзя было бесконечно ждать. что мешает оставить открытой ту форму со случайным числом?
 | 
 
 Но в данный момент это не главное - где хранить, в сессии или в базе.
 
 
 
 Цитата:
 | откуда же мы знаем, не видя кода? | 
 
 
 На странице с тестом
 // Динамический адрес для формы
 // Случайная часть динамического адреса
 $randomNumber = random_int(105000, 995000);
 
 // Создание подготовленного SQL запроса для обновления столбца
 $sql = "UPDATE user SET address_dynamic = ? WHERE token = ?";
 
 // Подготовка и выполнение SQL запроса
 $stmt = mysqli_prepare($db, $sql);
 mysqli_stmt_bind_param($stmt, "is", $randomNumber, $token);
 if (mysqli_stmt_execute($stmt)) {
 //echo "Data updated successfully";
 }
 
 Форма тестирования
 <form action="green-handler.php?d=<?php echo $randomNumber; ?>" method="POST">
 
 <div class="radiobutton-group">
 <input type="radio" id="button1" name="ball" value="100">
 <label for="button1">0</label>
 
 <input type="radio" id="button2" name="ball" value="1">
 <label for="button2">1</label>
 
 <input type="radio" id="button3" name="ball" value="2">
 <label for="button3">2</label>
 
 <input type="radio" id="button4" name="ball" value="3">
 <label for="button4">3</label>
 
 <input type="radio" id="button5" name="ball" value="4">
 <label for="button5">4</label>
 
 <input type="radio" id="button6" name="ball" value="5">
 <label for="button6">5</label>
 
 <input type="radio" id="button7" name="ball" value="6">
 <label for="button7">6</label>
 
 <input type="radio" id="button8" name="ball" value="7">
 <label for="button8">7</label>
 
 <input type="radio" id="button9" name="ball" value="8">
 <label for="button9">8</label>
 
 <input type="radio" id="button10" name="ball" value="9">
 <label for="button10">9</label>
 
 <input type="radio" id="button11" name="ball" value="10">
 <label for="button11">10</label>
 </div>
 
 <button class="start" type="submit">Далее</button>
 </form>
 
 
 
 В обработчике green-handler.php
 
 
 Вот так, вместе с другими элементами, мы извлекаем из базы динамическую часть адреса (переменная $address_dynamic)
 
 $sql = "SELECT step, new_topics, old_topics, limit_seans, address_dynamic FROM user WHERE token = ?";
 
 // Подготовка и выполнение SQL запроса
 $stmt = mysqli_prepare($db, $sql);
 mysqli_stmt_bind_param($stmt, "s", $token);
 if (mysqli_stmt_execute($stmt)) {
 // Привязка результатов запроса к переменным
 mysqli_stmt_bind_result($stmt, $step, $new_topics, $old_topics, $limit_seans, $address_dynamic);
 
 // Получение и вывод значений столбцов
 mysqli_stmt_fetch($stmt);
 }
 
 
 А здесь производим проверку
 
 // Проверка динамической части адреса для отсечения внешнего вызова
 if(isset($_GET['d'])) {
 if(!ctype_digit($_GET['d'])) die('<p class="error">Запрещённая операция. 55 <a href="/">На главную</a></p>');     // В адресе должный быть только цифры
 if($address_dynamic != $_GET['d']) die('<p class="error">Запрещённая операция. 56 <a href="/">На главную</a></p>');     // Не совпадают адреса
 }
 else die('<p class="error">Запрещённая операция. 58 <a href="/">На главную</a></p>');
 
 И почему-то получается, что примерно 1 раз на 200-300 ответов выводится сообщение об ошибке 58.
 
 Чтобы выйти на проблему, я организовал запись в текстовый файл пары адресов из базы и полученные через GET.
 
 Вот последние результаты:
 
 address_dynamic 626890 | $-_GET['d'] 626890
 address_dynamic 748117 | $-_GET['d'] 748117
 address_dynamic 467814 | $-_GET['d'] 626890
 
 В последней строке запись, после которой диагностирована ошибка. Адрес в базе именно такой (467814), а по GET пришел другой (626890). Видно, что такое число (626890) было на два цикла раньше. Похоже, что браузер, почему то, извлек старый адрес из кеша и решил его передать вместо требуемого?
 
 (На всех страницах стоит
 header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
 header("Cache-Control: post-check=0, pre-check=0", false);
 header("Pragma: no-cache");)
 
 
 |  | Всего записей: 351 | Зарегистр. 07-09-2016 | Отправлено:  11:25 07-11-2024  | Исправлено: Vladsvn,   18:16 07-11-2024
 | 
 |