How to check if radio button contains correct answers? - php

I have 2 tables in my database, 1 for questionnaires and 1 for correct answers. both have id linked to each other. code for displaying questions
while($row = $result->fetch_assoc()) {
echo "<br><label>". $row["Question"] ."</label><br><br>";
echo "<input type='radio' name='ans' value='ans1'>". $row["AnswerA"] ."</label><br>";
echo "<input type='radio' name='ans' value='ans2'>". $row["AnswerB"] ."</label><br>";
echo "<input type='radio' name='ans' value='ans3'>". $row["AnswerC"] ."</label><br>";
}
and then when user hits submit, the it should check if the radio button which contains the correct answer. code for checking answers
while($row = $result->fetch_assoc()) {
if(isset($_POST['submit'])){
if($_POST['ans']== $row["CorrectAns"]) {echo "Correct";}
else {echo "Incorrect";}
}
}
I think this will work for only one question. However I have about 20 questions and 3 radio buttons each. What addition should i add while checking the answer? I am trying to avoid javascript in this one but if there is a simple js solution I am open for it

First, reduce the database round trips and reduce rows fetched from database.
If you have multiple questions, get all the correct answers from database for these questions. Then create one array with correct answers $answers[question_id] = $answer;.
Then check for all the answers submitted by the user with actual answers.
<?php
if(isset($_POST['submit'])){
// $_POST['ans'] is array for all questions
$submittedAnswers = [];
$correctAnswers = [];
foreach ($_POST['ans'] as $questionID => $answer) {
$submittedAnswers[$questionID] = $answer;
}
// use mysql binding for actual query in production
//$sql = "select * from answers where Question_ID in {" . implode(',', array_keys($submittedAnswers)) . "}";
while($row = $result->fetch_assoc()) {
$correctAnswers[$row["Question_ID"]] = $row["CorrectAns"];
}
$failedQuestions = [];
foreach ($submittedAnswers as $questionID => $answer) {
if ($answer != $correctAnswers[$questionID]) {
$failedQuestions[] = $questionID;
}
}
}

Related

Populate array with values from different <option> drop down

I find this concept kinda confusing.
So basically i have a while loop in PHP that is used to retract display a question and its possible answers from a database. I also have populated a drop down list ( using select tag) with those possible answers. What im trying to achieve is, through a form, to send an array with values from all the currently selected options of the tag. This is the part of the code if that makes it easier to understand.
echo "<select name='quiz_question' id='quiz_question' required>";
while ($row = $result2->fetch_assoc()) {
$answer = $row['answer'];
$answer_id = $row['id'];
echo "<option value='$answer_id'>$answer</option>";
}
echo "</select>";
Any ideas on how i could achieve populating an array with elements that have the same value name since they are in a loop it would be great.
Found the answer that i was looking for. Posting it here in case someone else stumbles across my question.
Bare in mind that i'm populating my array with "id" which is an integer.
echo "<select name='Quiz_answers[]' id='quiz_question' >";
while ($row = $result2->fetch_assoc()) {
$answer = $row['answer'];
$answer_id = $row['id'];
echo "<option value='$answer_id'>$answer</option>";
}
echo "</select>";

How to distribute the results retrieved from database into individual pages?

I'm facing such a problem,
I have a database bank with lots of questions and their joined answers 'multiple choice system'!
I wrote a PHP script to retrieve (15) questions each time a user enters the page, 'index.php' as a radio-buttons.
Now my bass asked me to change the method of showing the questions! so, instead of 15 questions at the same page! he asked to show one question per time, something like this:
================================================================================
1. Question TEXT:
a. 1st variant
b. 2nd variant
c. 3rd variant
d. 4th variant
<NEXT QUESTION>
================================================================================
so by clicking on the button which is a "submit" the script should redirect me to the second part of the file which must show the second question, and from the second as shown above to the third --> forth --> ... --> 15th question
================================================================================
1st question is: Correct //This part will check the correction/incorrection of the previous question -_-
2. Question2 TEXT:
a. 1st variant
b. 2nd variant
c. 3rd variant
d. 4th variant
<NEXT QUESTION>
================================================================================
bottom line, I am able to bring a 15 question on the page and after checking the answers I give the results. but I could figure out how to distribute these questions into individual pages!! as
'index.php?question=1'
'index.php?question=2'
'index.php?question=3'
...
'index.php?question=15'
Thank you guys!
so as I said, I wanted to distribute the results retrieved from one query into individual pages, and I came up with this idea,
1. Did the same query
SELECT * FROM database ORDER BY RAND() LIMIT 10
then I saved the IDz of the retrieved questions into an array just like that
$id = array();
$_SESSION[corr] = 0;
$_SESSION[incorr] = 0;
while ($row = mysql_fetch_assoc($query) {
$id[] = $row[ID];
}
Then I saved the array into a SESSION to pass it in every required page as follows
$_SESSION[ID] = $id;
after that I set a link such as
echo "<a href=test.php?question=1>Click To Start</a>";
and last but not least did something like this
if ($_REQUEST['question'] == '1') {
$id = $_SESSION['id'];
$sql = mysql_query("SELECT * FROM `test` WHERE `id` = '$id[0]'") or die("Error" .mysql_error());
$row = mysql_fetch_assoc($sql);
echo "<font color=green>Correct: " .$_SESSION[corr]. "</font></br>";
echo "<font color=red>Incorrect: " .$_SESSION[incorr]. "</font></br>";
echo "$row[v]<br>";
echo "<form action='test.php?question=2' method='POST'>";
echo "<input type=radio name=answer1 value=1>$row[o1]</input><br>";
echo "<input type=radio name=answer1 value=2>$row[o2]</input><br>";
echo "<input type=radio name=answer1 value=3>$row[o3]</input><br>";
echo "<input type=radio name=answer1 value=4>$row[o4]</input><br>";
echo "<input type=submit name=submit value=Check>";
echo "</form>";
$_SESSION['previous_id'] = $row['id'];
exit;
and in the next part "test.php?question=2"
I firstly checked if the previous question was answered correctly as the following
if ($_REQUEST['question'] == '2') {
$id = $_SESSION['id'];
$answer = $_POST['answer1'];
$grade = mysql_query("SELECT * FROM `test` WHERE `id` = {$_SESSION['previous_id']}") or die();
$right = mysql_fetch_assoc($grade);
if ($answer == $right[g]) {
$_SESSION['corr']++;
echo "<font color=green>Correct</font></br>";
}
else {
$_SESSION['incorr']++;
echo "<font color=red>Incorrect, check lesson #".$right[lvl]."</font></br>";
}
$sql = mysql_query("SELECT * FROM `test` WHERE `id` = '$id[1]'") or die("Error" .mysql_error());
$row = mysql_fetch_assoc($sql);
echo "$row[v]<br>";
echo "<form action='test.php?question=3' method='POST'>";
echo "<input type=radio name=answer2 value=1>$row[o1]</input><br>";
echo "<input type=radio name=answer2 value=2>$row[o2]</input><br>";
echo "<input type=radio name=answer2 value=3>$row[o3]</input><br>";
echo "<input type=radio name=answer2 value=4>$row[o4]</input><br>";
echo "<input type=submit name=submit value=Check>";
echo "</form>";
$_SESSION['previous_id'] = $row['id'];
exit;
}
That worked just 100% as I wanted, but it is just not feeling professional, because I had to rewrite that code, or copy and edit the same above shown codes lots of times, considering I am trying to post 10 or 15 questions separately..
hopefully that helps some one else!

The "LOGIC" in Quizes PHP+MySQL

I have a Database (MySQL) where is a table called: "dbtest" has the following fields,
id + v + o1 + o2 + o3 + o4 + g
to clarify that:
v: are the questions field
o1: the first answer
o2: the second
o3: third
o4: forth
g: is the right answer, where I put the number of the right answer for example, if I had a question with a correct answer "o3" the value of "g" should be "3"
(I did that myself thinking would be easier hopefully)
We yet did not reach the point I know, the thing is that I'm building a quiz program standing on the previous scheme, I made a page that calls the questions from the database and post them one below the other, the code was as the following:
<?php
include "config.inc";
$SQL = "SELECT * FROM test";
$query = mysql_query($SQL) or die();
echo "<form action=grade.php method=POST>";
while ($row = mysql_fetch_assoc($query)) {
echo "<p>$row[id]. ";
echo "$row[v]<br>";
echo "<input type=radio name=answer[$row[id]] value=$row[o1]>$row[o1]</input><br>";
echo "<input type=radio name=answer[$row[id]] value=$row[o2]>$row[o2]</input><br>";
echo "<input type=radio name=answer[$row[id]] value=$row[o3]>$row[o3]</input><br>";
echo "<input type=radio name=answer[$row[id]] value=$row[o4]>$row[o4]</input><br>";
}
echo "<input type=submit name=submit value=Check>";
echo "</form>";
?>
The problem is when I wanted to write the "grade.php" page I fell off an edge, I absolutely lost, I could do it if there was just one question in the database, so no need to enter a loop, but since the database is expected to receive tons of question I lost control.
I was trying something like,
<?php
include "config.inc";
$SQL = "SELECT * FROM test";
$query = mysql_query($SQL) or die();
$n = 0;
while ($row = mysql_fetch_assoc($query)) {
$n++;
$ques[$n] = $_POST['answer'];
if ($ques[$n] == $row[g]) {
echo "<font color=green>Correct</font>"; }
else {
echo "<font color=red>Incorrect<br></font>"; }
}
?>
But did not make it, all what I need is to process the questions and give right/wrong answers, for every right answer (+1) for every wrong one (-1) then I will post the sum mathematically.
In HTML your have to change radio button :
No need to add </input>,
For value you set answer number,
Add quotes for attributes
echo '<input type="radio" name="'.$answer[$row['id']].'" value="1" />'.$row['o1'].'<br>';
echo '<input type="radio" name="'.$answer[$row['id']].'" value="2" />'.$row['o2'].'<br>';
echo '<input type="radio" name="'.$answer[$row['id']].'" value="3" />'.$row['o3'].'<br>';
echo '<input type="radio" name="'.$answer[$row['id']].'" value="4" />'.$row['o4'].'<br>';
In PHP :
You create some variables to store good and bad answers,
You check if value of $row['g'] is equal to answer number
$query = mysql_query("SELECT * FROM test") or die();
$good = 0; // Number of good answers.
$bad = 0; // Number of bad answers.
while ($row = mysql_fetch_assoc($query))
{
if ( $_POST['answer'][$row['id']] == $row['g'] )
{
echo '<span style="color: green;">Correct</span>';
$good++;
}
else
{
echo '<span style="color: red;">Incorrect</span>';
$bad++;
}
}

Pulling a survey with multiple answers from a database

I have a working survey that pulls each question and any related answers from multiple tables. Each question is stored in the following table:
tblQuestions, with the fields:
qID
qText.
The related answers are stored in the table:
tblPossAnswers, with the fields:
aID
qID
answerText.
So, I would have 3 possible answers for each question. My sql to pull everything is:
select * from tblQuestions, tblPossAnswers where
tblPossAnswers.qID = tblQuestions.qID
order by tblQuestions.qID ASC
And my PHP to display it:
while ($row = mysql_fetch_array($result)) {
echo "<p>" . $row['qText'] . "</p><br />";
echo "<input type='radio' name='".$row['qID']."' value='".$row['aID']."' />";
echo $row['answerText'];
}
The problem is this is displaying the qText every time it displays a possible answer. So it looks like:
Question 1
Possible answer 1
Question 1
Possible answer 2
Question 1
Possible answer 3
Question 2
Possible answer 1
Question 2
Possible answer 2
Question 2
Possible answer 3
What I would like to do is have the qText only display when the first possible answer is pulled. I'm still somewhat of a newb to MySQL, so the solution might be something very simple that I'm just not seeing.
You can either test for whether the question has changed within your PHP loop:
while ($row = mysql_fetch_array($result)) {
if ($row['qID'] != $lastQuestionID) {
echo "<p>" . $row['qText'] . "</p><br />";
$lastQuestionID = $row['qID'];
}
echo "<input type='radio' name='".$row['qID']."' value='".$row['aID']."' />";
echo $row['answerText'];
}
Or else you can group the MySQL results by question using GROUP_CONCAT, specifying a separator on which you then split the answers in PHP:
select *, group_concat(answerText separator char(30)) as answers
from tblQuestions join tblPossAnswers using (qID)
group by tblQuestions.qID
order by tblQuestions.qID ASC
Then:
while ($row = mysql_fetch_array($result)) {
echo "<p>" . $row['qText'] . "</p><br />";
foreach (explode(chr(30), $row['answers']) as $answer) {
echo "<input type='radio' name='".$row['qID']."' value='".$answer."' />";
echo $answer;
}
}
No need to change anything in sql just change php slightly as following
while ($row = mysql_fetch_array($result)) {
if ($row['qText'] != $lastQuestion) {
echo "<p>" . $row['qText'] . "</p><br />";
$lastQuestion = $row['qText'];
}
echo "<input type='radio' name='".$row['qID']."' value='".$row['aID']."' />".$row['answerText'];
}

PHP checkbox problem

I am going nuts here, I have an array of checkboxes from a form that I am trying to $_POST with PHP. EVERYTHING on my form posts fine except the check boxes. The checkboxes DO post, but in the wrong order. For instance when I want checkbox[0] and checkbox[2] I actually get checkbox[0] and checkbox[1].
I have tried many different ways to get the value of the checkbox, including isset but I still have the same problem. I just need the checkbox value of on to be stored in my database if the checkbox is indeed checked.
My code is below. $in_production is the checkbox. I can provide the code that generates the checkbox too if it is needed.
Thanks in advance.
if ($_GET['action'] == 'Edit_Product'){
include("../dbinfo.php");
$q_id = $_GET['q_id'];
for ($i = 0; $i < count($_POST['p_id']); $i++){
$result = mysql_query('SELECT * FROM products WHERE q_id = '.$q_id);
$num = mysql_num_rows($result);
$p_id = ($_POST['p_id'][$i]);
$in_production = ($_POST['in_production'][$i]);
$p_name = ($_POST['p_name'][$i]);
$p_price = ($_POST['p_price'][$i]);
$p_name_conflict = FALSE;
for ($ii = 0; $ii < $num; $ii++){
$row = mysql_fetch_array($result);
$p_name_conflict_check = $row['p_name'];
$p_id_conflict_check = $row['p_id'];
if($p_name_conflict_check == $p_name &&
$p_id_conflict_check != $p_id){
$p_name_conflict = TRUE;
}
}
if ($p_name_conflict == FALSE){
$query = "UPDATE products SET p_name='$p_name',
p_price='$p_price', in_production='$in_production',
last_modified=CURDATE() WHERE p_id = '$p_id'";
mysql_query($query);
}
else{
$update_failures =+1;
}
}
mysql_close($link);
if($update_failures == 0){
header("Location: Products_Updated.html");
}
elseif ($update_failures != 0){
header("Location: Products_Exist.php?update_failures=".$update_failures);
}
}
P.S. I don't know why but the code block icons are not present on SO right now... so my code is not all pretty. Also, I know my code is horribly inefficient, but I am just trying to get this working right now, then fine tune later. I am open to efficiency suggestions as well, but that is not my primary objective with this question.
EDIT: Here is the form from the HTML...
<form id="form" name="form" method="post" action="/Management/Products/Product_Management.php?action=Edit_Product&q_id=<?php echo "$q_id" ?>">
<?php
include("../dbinfo.php");
$result = mysql_query('SELECT * FROM products WHERE q_id =' . $q_id);
$num = mysql_num_rows($result);
mysql_close($link);
for ($i = 0; $i < $num; $i++){
$row = mysql_fetch_array($result);
$p_id = $row['p_id'];
$p_name = $row['p_name'];
$p_price = $row['p_price'];
$in_production = $row['in_production'];
$date_added = $row['date_added'];
$last_modified = $row['last_modified'];
if($in_production == 'on'){
$checked = 'checked';
}
else{
$checked = '';
}
echo "<div>Product ID# " . $p_id . "<label style=\"font-style:italic\"> (Originally added on " . $date_added . ", last modified on " . $last_modified . ")</label></div><br/>";
echo "<input id=\"p_id" . $p_id . "\" class=\"text\" type=\"hidden\" name=\"p_id[]\" value=\"" . $p_id . "\"/>";
echo "<label>Product Name *</label><br/>";
echo "<div><label style=\"font-style:italic\">(Product still in production <input type=\"checkbox\" name=\"in_production[]\"" . $checked . " style=\"width:15px\"/>)</label></div>";
echo "<input id=\"p_name" . $p_id . "\" class=\"text\" type=\"text\" name=\"p_name[]\" maxlength=\"20\" onfocus=\"on_focus(this)\" onblur=\"on_blur(this)\" value=\"" . $p_name . "\"/><br/><br/>";
echo "<label>Product Price *</label><br/>";
echo "<div><label style=\"font-style:italic\">(Without taxes)</label></div>";
echo "<input id=\"p_price" . $p_id . "\" class=\"text\" type=\"text\" name=\"p_price[]\" maxlength=\"6\" onkeypress=\"return currency(this, event)\" onchange=\"currency_format(this)\" onfocus=\"on_focus(this)\" onblur=\"on_blur(this)\" value=\"" . $p_price . "\"/><br/><br/><br/><br/>";
}
?>
<input class="button" type="button" value="Submit" onclick="product_edit_form_check()"/><br/><br/>
</form>
It would be helpful if you could post some of the HTML-part so we could see how you create your form. It seems you're generating your checkboxes without indexes in your array, so all checkboxes have the name/id "checkbox[]", which is ok if you don't care about the index, but if posted, the array will be numbered starting from "0" and then counting up which is the reason why you'll get "0" and "1" posted, even if "0" and "2" were checked.
Try to give your checkboxes' name/id numbers when generating the HTML, like "checkbox[0]", "checkbox[1]", "checkbox[2]", and so on. So when checkbox 0 and 2 are checked, you should get those values (including the correct index) posted.
The thing you have to bear in mind with HTML checkboxes is that they only POST a value if they are checked. If they are not checked, they don't get posted.
With this in mind, you should give each checkbox a name and then test for it in the POST to detect whether or not it has been passed back.
if (isset($_POST['MyCheckbox'])) {
} // else it wasn't checked!
Show us the HTML for the checkboxes.
Also, you have an SQL injection attack waiting to happen - a user can get any SQL they like onto the end of your query. Something like this illustrates what you should do with untrusted data:
//we're expect a number, so ensure we get one
$q_id = intval($_GET['q_id']);
//get into the habit of quoting query params,
//or better yet, use a wrapper library to help you
$sql="select * from products where q_id='".mysql_real_escape_string($q_id)."'";
If you declare checkbox name like (p_id[]), it's like telling PHP "I'm adding element to an array, enumerate it for me". Like in php $array[] = 't'; If you have several form elements with different names and you want to have synchronised IDs you HAVE to add index because otherwise browser will/may send only selected ones and PHP will enumerate it continuously.
You can specify indexes by using p_id[INDEX] and so on, where index is anything (I suggest numeric or alphanumeric).
Also, checkbox value can be altered and I encourage you to do it. value="1" helps, then you're sure that you get it.
<input type="checkbox" name="p_id[0]" value="1" />
In PHP you'll receive
$_POST['p_id'] ===> array(0 => 1);
et caetera.

Categories