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++;
}
}
Related
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;
}
}
}
I'm making a quiz for my students. I would like to make it in such a way that you can only see question 2 after you solved question 1 (and so on).
My current idea is to make a web page for every question with a form on it:
<FORM action="test.php" method="post">
<I>12 is the right answer:</I>
<INPUT TYPE="text" NAME="name" SIZE="20" MAXLENGTH="30"><BR>
<INPUT TYPE="submit" VALUE="send">
</FORM>
And afterwards, I try to redirect from test.php to next.php whenever the answer is 12 and to current.php when the answer is not 12. Though, I am not able to make this work. Can anyone help me?
Have not written php code for a while now but will try to guide you.
No, you should not create a web page for each question. That is not a scalable approach. Imagine if you have to store 1000 questions over time,period.
Instead use dynamic page loading concept in php. Here what you should be doing:
1.Create a table in whichever database you are using with fields like
Id,question,option1,option2,option3,option4,correctAnswer
Create a php page like quiz.php which reads the question based on questionId stored in the session variable.
Lets say you show the first question in front page, displad the options and showed a submit button.
When the user clicks submit button what should happen is that the same quiz.php page will get called courtsy <form action="quiz.php"> with the user selected answer.
You can then check for the correct answer in php file since you have the correct answer stored in a variable which stores the database fetched result of first question, and if that is correct answer you can update the session with id of next question (increment by 1 or any other mechanism) and query the database table for that question id .
Your html should be written in such a way away which reads the current value stored in $row variable, which stores the result of the query w.r.t to questionId stored in session.
little bit of the code :
quiz.php file:
<?php
$con=mysql_connect($dbserver,$dbusername,$dbpassword);
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname, $con);
// Check user answer for previous question
if (isset($_POST['submit'])) {
if(isset($_SESSION['question_id'])){
$previous_question_id = (int) $_POST['question_id'];
// Query database
$getQuestion = "SELECT * from questions_table where id =
$previous_question_id";
$resultOfQuestion = mysqli_query($conn, $getQuestion);
$correct = $row_get_question['correctAnswer'];
$selected_radio = $_POST['answer'];
if ($selected_radio == $correct)
echo "THAT ANSWER IS CORRECT";
$_SESSION['question_id'] = $previous_question_id +1;
$getQuestion = "SELECT * from questions_table where
(id=".$_SESSION['question_id'].")";
$resultOfQuestion = mysqli_query($conn, $getQuestion);
else
echo "THAT ANSWER IS WRONG!";
}
}
if(!isset($_SESSION['question_id'])) {
$_SESSION['question_id']="0";
$getQuestion = mysql_query("SELECT * FROM questions WHERE
(id=".$_SESSION['question_id'].")";
$resultOfQuestion = mysqli_query($conn, $getQuestion);
}
echo "<form action='quiz.php' method='post'>";
while($row = mysql_fetch_array($resultOfQuestion)){
echo " <b>" . $row['question'] . "</b>";
echo "<input type='radio' value='' name='answer' checked />";
echo $row['option1']; echo "<br />";
echo "<input type='radio' value='' name='answer' />";
echo $row['option2'];echo "<br />";
echo "<input type='radio' value='' name='answer' />";
echo $row['option3'];echo "<br />";
echo "<input type='radio' value='' name='answer' />";
echo $row['option4'];echo "<br />";
echo "<input type='submit' name='next' value='next' />";
}
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 form already has an existing submit button which you can select difficulty(1st combo) and location(2nd combo) and then i submit this to display a video and a text field
under the field i have an addtional drop down box which is yes or no
then inside this code i want to submit a separate value using an if inisde an if it works fine on the 1st difficulty and location in the lists but nothing else and i cant see what im doing wrong a new pair of eyes would be great PS i will be upgrading this to PDO eventually
<?php
if(strpos($drop, 'norm') !== false && $ruavalue == 0)
{
Echo "RUA: ";
$RUAresult = mysql_query("SELECT Answer FROM options");
echo "<select name='ruacombo'>";
while($RUArow = mysql_fetch_assoc($RUAresult))
echo "<option value = '".$RUArow['Answer']."'>".$RUArow['Answer']."</option>";
echo "</select>";
echo '<form action="" method="post">';
echo "<input name=\"boss\" type=hidden value=".$_POST['tier_two'].">";
echo "<input name=\"main\" type=hidden value=".$_COOKIE['ID_my_site'].">";
echo '<input type="submit" name="ruasubmit" value="RUA!" />';
echo '</form>';
if (isset($_POST['ruasubmit']))
{
$ruaboss = $_POST['boss'];
$ruauser = $_POST['main'];
$ruasql = "UPDATE `RUASEXCELL` SET `$ruaboss`=1 WHERE Username = '$ruauser'";
$add_rua = mysql_query($ruasql);
}
In your while loop, you need to access the associative array keys as a string like so:
while($RUArow = mysql_fetch_assoc($RUAresult))
echo "<option value = '".$RUArow['Answer']."'>".$RUArow['Answer']."</option>";
Also, please look into using mysql_real_escape_string() to prevent SQL injection. In its current state, this script, and your database can be blown to pieces by a stray quote.
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.