Добрый день. Есть форма со списком названий тестов. Подскажите пожалуйста, как лучше объединить их в один общий тест и чтобы в нем они открывались друг за другом без вывода промежуточных результатов? Чтобы после нажатия кнопки "Завершить" подсчитывались результаты по всем категориям, с сохранением в БД. Но пользователю не показывались эти результаты. Спасибо за помощь. Код (Text): <?php include_once 'db.php'; $do = trim(strip_tags($_GET['do'])); if ($do == 'save') { $title = trim($_POST['title']); $res = $db->prepare("INSERT IGNORE INTO tests (`title`) VALUES (:title)"); $res->execute([ ':title' => $title, ]); $testId = $db->lastInsertId(); $questionNum = 1; while (isset($_POST['question_' . $questionNum])) { $question = trim($_POST['question_' . $questionNum]); if (empty($question)) { continue; } $res = $db->prepare("INSERT IGNORE INTO questions (`test_id`, `question`) VALUES (:test_id, :question)"); $res->execute([ ':test_id' => $testId, ':question' => $question, ]); $questionId = $db->lastInsertId(); $answerNum = 1; while (isset($_POST['answer_text_' . $questionNum . '_' . $answerNum])) { $answer = trim($_POST['answer_text_' . $questionNum . '_' . $answerNum]); $score = trim($_POST['answer_score_' . $questionNum . '_' . $answerNum]); if (empty($answer)) { continue; } $res = $db->prepare("INSERT IGNORE INTO answers (`question_id`, `answer`, `score`) VALUES (:question_id, :answer, :score)"); $res->execute([ ':question_id' => $questionId, ':answer' => $answer, ':score' => $score, ]); $answerNum++; } $questionNum++; } $resultNum = 1; while (isset($_POST['result_' . $resultNum])) { $result = trim($_POST['result_' . $resultNum]); $scoreMin = trim($_POST['result_score_min_' . $resultNum]); $scoreMax = trim($_POST['result_score_max_' . $resultNum]); $res = $db->prepare("INSERT IGNORE INTO results (`test_id`, `score_min`, `score_max`, `result`) VALUES (:test_id, :score_min, :score_max, :result)"); $res->execute([ ':test_id' => $testId, ':score_min' => $scoreMin, ':score_max' => $scoreMax, ':result' => $result, ]); $resultNum++; } header ('Location: admin.php?do=list'); } if ($do != 'add') { $do = 'list'; } ?> <!doctype html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Система тестирования</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <link rel="stylesheet" href="css/app.css"> </head> <body> <div class="container"> <div class="row justify-content-center"> <?php include_once 'inc/' . $do . '.php'; ?> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script src="js/app.js"></script> </body> </html>
Надо прояснить логику работы приложения. Как названия тестов попадают на страницу? Из примера можно догадаться, как данные записываются в базу данных. Нужно нарисовать себе схему начиная с загрузки главной страницы и действий пользователя. Проследить путь передачи данных. Решение придет само.
Просто по всем вопросам сделайте перемещение (с сортировкой в первую очередь по тесту, особенно если вопросы идут «вразнобой»). При переходе на новый тест, если нужно, сохраняйте результаты предыдущего. Для этого нужно хранить в сессии id тек. теста. Чтобы нельзя было открыть произвольный вопрос, храните в сессии и id тек. или след. вопроса (понятно, что при хранении id вопроса id теста в общем-то можно не хранить). В итоге можно сделать даже вывод всех вопросов по одному адресу. --- Добавлено --- Я бы, наверное, хранил в БД ответ пользователя на каждый вопрос и не давал его перезаписывать (пока админ не положит этот ответ в «архив»). Можно просто перед тестированием пользователей создавать новый объект «тестирование» и не давать пользователям повторно отвечать на вопросы одного и того же тестирования.
@Яна Литвинова попробуйте использовать в коде комментарии для себя. Объясняйте себе, что делает этот участок кода. Тогда проще будет понять, как и что работает. Для неизвестной функции можно использовать поиск, где прочитать назначение.