I really need your help. After 4 hours to pass. I have a test. I get questions from a DB.

<?php $db = mysql_connect('localhost', 'ItEconom', '22304qqq'); mysql_select_db('IT', $db); $myrow = mysql_query("SELECT question, var1, var2, var3, var4,var5,var6,var7 FROM testProc3 "); $count = 0; $arr[0] = 0; While ($count < 20) { $a = false; while (!$a) { $count2 = 0; $num = rand(1, mysql_num_rows($myrow) - 1); for ($i = 0; $i < count($arr); $i++) { if ($num != $arr[$i]) $count2++; } if ($count2 == count($arr)) { $arr[$count] = $num; $a = true; } } $count++; echo "<form action = 'handler.php' method = 'Post' name = 'Post'>"; printf("%s<br><label><input type = 'radio' name = 'id[%s][1]' value = '1'></label> а) %s<br><input type = 'radio' name = 'id[%s][2]' value = '2'></label> б) %s<br><input type = 'radio' name = 'id[%s][3]' value = '3'></label> в) %s<br>", mysql_result($myrow, $num, 'question'), $num, mysql_result($myrow, $num, 'var1'), $num, mysql_result($myrow, $num, 'var2'), $num, mysql_result($myrow, $num, 'var3')); if (mysql_result($myrow, $num, 'var4') != null) { echo "<input type = 'radio' name = id[" . $num . "][4] value = '4'></label> г) " . mysql_result($myrow, $num, 'var4') . '<br>'; } if (mysql_result($myrow, $num, 'var5') != null) { echo "<input type = 'radio' name = id[" . $num . "][5] value = '5'></label> д) " . mysql_result($myrow, $num, 'var5') . '<br>'; } if (mysql_result($myrow, $num, 'var6') != null) { echo "<input type = 'radio' name = id[" . $num . "][6] value = '6'></label> е) " . mysql_result($myrow, $num, 'var6') . '<br>'; } if (mysql_result($myrow, $num, 'var7') != null) { echo "<input type = 'radio' name = id[" . $num . "][7] value = '7'></label> ж) " . mysql_result($myrow, $num, 'var7') . '<br>'; } echo '<br>'; } echo ' <input type="submit" value = "Показать результаты"/>'; echo "</form>"; ?> 

Here is the handler:

 <?php $db = mysql_connect('localhost', 'ItEconom', '22304qqq'); mysql_select_db('IT', $db); $pravOtv = 0; foreach ($_POST['id'] as $i) { //echo $i; foreach ($i as $j) { $otv = 0; $svet = 0; for ($count = 1; $count < 8; $count++) { $tmp = mysql_query("select * FROM testProc3"); echo mysql_result($tmp, $i, 'otv' . $count); if (intval(mysql_result($tmp, $i, 'otv' . $count))) ++$svet; // Проверяю сколько всего правильных вариантов ответа в БД if ($j == mysql_result($tmp, $i, 'otv' . $count)) // Проверяю совпадают ли мои ответы с правильными { $otv++; } } } if ($svet == $otv) $pravOtv++; // Если кол-во вариантов ответа совпало с решенными, то имеем один правильный ответ. } echo ' <div class = "print" >Правильных ответов: ' . $pravOtv . '</div>'; ?> 
  • As a result, I constantly receive: correct answers: 0 PS It does not matter that the code is incorrect. At the moment, the main thing is that he earned and I was allowed to take the exam) - Radik Kamalov
  • Will you pass your exam to your script? - zenith

1 answer 1

The code, alas, is impossible to read and disassemble, some kind of jumble. Plus, it is conceptually incorrect - if it somehow works, it will be an accident, not a normal behavior. And it is far from a fact that this accident will happen again upon surrender.

No offense, but it is much easier to throw out and rewrite in the mind than to fix it. At least in the dances in the cycle, where some kind of data structure with questions was composed, I got lost. Looking at night to make out what is going on there (meaningful variable names $a do not contribute) is difficult.

In the table, the primary key needs an id column that uniquely identifies the question. Because two SELECT * FROM table samples can return rows in a different order. And you are attached to this order.

It is possible without id, but then describe the structure of the table, in particular, what is the primary key. You may have to use, for example, SHA1 from the question text (assuming that there will be no collision). But it is better to add a surrogate primary key ( id ), if it doesn’t exist, it takes one second and simplifies the situation.

Issue of questions:

 <?php // Функции `mysql_*` давно deprecated. Ими не стоит пользоваться. $db = new PDO("mysql:host=localhost;dbname=IT", "ItEconom", "22304qq"); // Выбираем 20 вопросов, сортируя по случайным числам, чем обеспечиваем // перемешивание. $sth — результат запроса, дальше вытаскиваем массив // массивов в $questions. $sth = $db->query("SELECT * FROM testProc3 ORDER BY RAND() LIMIT 20"); $questions = $sth->fetchAll(); $letters = array("а", "б", "в", "г", "д", "е", "ж"); ?> <!DOCTYPE html> <html> <head> <title>Тест</title> </head> <body> <form action="handler.php" method="post"> <?php // Выводим список вопросов. Не очень красиво, но обойдемся без шаблонизатора. foreach ($questions as $question) { ?> <section> <p><?php echo htmlspecialchars($question["question"]); ?></p> <p> <?php // Пробегаемся по столбцам `var$i` for (var i = 1; i < 8; i++) { // Если очередное поле NULL — закругляемся с этим вопросом if (is_null($question["var$i"])) break; ?> <label> <input type="radio" name="answer[<?php echo $question["id"] ?>]" value="<?php echo $i; ?>"> <?php echo $letters[$i], ") ", htmlspecialchars($question["var$i"]); ?> </label> <?php } ?> </p> </section> <?php } ?> <input type="sumbit" value="Получить результаты"> </form> </body> </html> 

Checking answers:

 <?php $db = new PDO("mysql:host=localhost;dbname=IT", "ItEconom", "22304qq"); // Подготавливаем запрос. Каждый раз как будем делать $check->execute(...) // будет выполняться такой запрос, с подставленным значением вместо «?» $check = $db->prepare("SELECT otv FROM testProc3 WHERE id = ?"); $correct = 0; // Пробегаемся по ответам foreach($_POST["answer"] as $id => $answer) { // Выбираем правильный ответ для вопроса с ID = $id // NB: `execute` хочет в аргументы массив, пусть даже из одного элемента. $check->execute(array($id)); if ($answer == $check->fetchColumn()) { // Правильный ответ — увеличиваем счетчик $correct += 1; } } ?> <!DOCTYPE html> <html> <head> <title>Результат</title> </head> <body> <p>Правильных ответов: <b><?php echo $correct; ?></b>.</p> </body> </html> 

One "but" - I did not understand about the "number of correct answers" (to the question). Assuming that you have <input type="radio" ...> , I will assume that the correct answer is one. If a lot - it would already be type="checkbox" and logic complication:

Then the form would be:

 <input type="checkbox" name="answer[<?php echo $question["id"] ?>][]" value="<?php echo $i ?>"> 

And when checking $answer we would have an array. Suppose the otv field stores the answers as a string, with numbers separated by commas. Then the verification code would be in the spirit of:

 $check->execute(array($id)); $correct_answer = explode(",", $check->fetchColumn()); // Массив правильных ответов // Вычисляем различия между массивами $diff = array_diff($answer, $correct_answer); if (count($diff) == 0) { // Пустой массив различий значит что их не было (порядок не важен, // тут массивами оперировали как множествами) $correct += 1; } 

(But it is unacceptable to have questions where there is not a single correct answer - then no answer[N][] will be passed on and we will ignore the existence of the question altogether. I hope this is acceptable - this layout saves us time by simplifying the processing of the form.

I did not check the code, I wrote in the browser. Adjusted for typos should work.

Update: Fixed errors, forgot to make fetchAll() in the first script and forgot the value of <input> 's. Now it seems like it should - check, alas, there is nowhere - neither a web server with PHP nor a MySQL / MariaDB server is in an accessible environment, but I’m too lazy to bet, sorry.