Comparing only the selected value in loop to avoid error message - php

I am trying to build a basic quiz system.The following code shows how user choose the answer using radio butto and the getresult.php compares the radio input value with answer column. In my database there is a question, opt1, opt2, opt3, opt4, and answer columns.
<form method="POST" action="getresult.php">
<label>Enter Your Name:</label><br>
<input type="text" name="name"><br><br>
<?php
$db = new mysqli("localhost", "root", "","learndb");
$stmt=$db->prepare("SELECT * FROM quiz");
$stmt->execute();
$result=$stmt->get_result();
echo "<form method='POST' action='getresult.php'>";
while($myrow = $result->fetch_assoc())
{
echo $myrow['id'];
echo ".";
echo $myrow['question'];
echo "<br>";
echo "<input type='radio' name='mycheck[".$myrow['id']."]' value=".$myrow['opt1'].">";
echo $myrow['opt1'];
echo "<br>";
echo "<input type='radio' name='mycheck[".$myrow['id']."]' value=".$myrow['opt2'].">";
echo $myrow['opt2'];
echo "<br>";
echo "<input type='radio' name='mycheck[".$myrow['id']."]' value=".$myrow['opt3'].">";
echo $myrow['opt3'];
echo "<br>";
echo "<input type='radio' name='mycheck[".$myrow['id']."]' value=".$myrow['opt4'].">";
echo $myrow['opt4'];
echo "<br><br>";
}?>
<input type="submit" name="submit" value="Get Results" class="btn btn-primary">
// getresult.php
<?php
extract($_POST);
$db = new mysqli("localhost", "root", "","learndb");
$stmt=$db->prepare("SELECT * FROM quiz");
$stmt->execute();
$result=$stmt->get_result();
$submit=isset($_POST['submit']);
$count=0;
if($submit)
{
while($myrow = $result->fetch_assoc())
{
if($mycheck[$myrow['id']]==$myrow['answer'])
{
$count=$count+1;
}
}
echo "Hello ";
echo $_POST['name'];
echo "<br>";
echo "You scored ";
echo "$count";
}
Everything is correct, but if I do not select a radio button from a question, i.e if I leave the question it displays undefined offset error which is obvious but how can I not display that. OR how can I compare only chosen options?

You should try array_key_exists() like this:
if(array_key_exists($myrow['id'], $mycheck)
&& array_key_exists('answer', $myrow)
&& $mycheck[$myrow['id']]==$myrow['answer'])
{
$count=$count+1;
}
Or better yet, request your answers from database based on validated rows.

When the form is submitted, the chosen values are passed as (for example):
mycheck[1]=2
mycheck[2]=3
mycheck[3]=1
mycheck[4]=2
...etc. Now if you leave one question unanswered, let's say question 2, then no value will be submitted to the server for that question, so the submitted values could be something like this:
mycheck[1]=2
mycheck[3]=1
mycheck[4]=2
When PHP stores this in $_POST[], it will be an associative array:
$_POST['mycheck'] === array(
'1' => 2,
'3' => 1,
'4' => 2
)
With extract($_POST) you get the following value for $mycheck:
$mycheck === array(
'1' => 2,
'3' => 1,
'4' => 2
)
Now the following loop in your code will still go through all questions:
while($myrow = $result->fetch_assoc())
{
if($mycheck[$myrow['id']]==$myrow['answer'])
{
$count=$count+1;
}
}
But (in the example) the check for question 2 will fail, because $myrow['id'] will equal 2, while $mycheck[2] does not exist. This produces the undefined offset error.
As an unanswered question obviously should not increase the count, you could solve this issue as follows: first test if the question was answered (does $mycheck have an entry for it?), and only if that is the case, retrieve the answer from that entry:
while($myrow = $result->fetch_assoc())
{
$id = myrow['id'];
if(array_key_exists($id, $mycheck) && $mycheck[$id]==$myrow['answer'])
{
$count=$count+1;
}
}
For the above extra test you can use array_key_exists, or isset.

A bit rusted on PHP, but ...
Have you tried using the isset() function? Or changing the error reporting level appropriately?
http://php.net/manual/pt_BR/function.error-reporting.php

Why don't you create a new radio button "Don't know " which would be initially checked
<input type="radio" name="" checked>
So by default that button will be checked.

Related

Array ( ['1'] => 1 ) 1 Notice: Undefined offset: 1 in C:\xampp\htdocs\HR\functions\functions_applicants.php on line 152 2

The code below is to display the quiz(questions and answers)
When submitting, I am getting error:
"Array ( ['1'] => 1 ) 1
Notice: Undefined offset: 1 in C:\xampp\htdocs\HR\functions\functions_applicants.php on line 152
2".
<form method="post" action="index.php?results">
<?php
for($i=1; $i<27; $i++) {
$query = query("SELECT * FROM assess_questions WHERE question_id =$i");
confirm($query);
while($row = fetch_array($query)) {
?>
<div>
<h4><?php echo $row['question']; ?></h4>
<input type="radio" name="quizcheck['<?php echo $row['question_id']; ?>']"
value=1><?php echo $row['A']; ?><br>
<input type="radio" name="quizcheck['<?php echo $row['question_id']; ?>']"
value=2><?php echo $row['B']; ?><br>
<input type="radio" name="quizcheck['<?php echo $row['question_id']; ?>']"
value=3><?php echo $row['C']; ?><br>
<input type="radio" name="quizcheck['<?php echo $row['question_id']; ?>']"
value=4><?php echo $row['D']; ?><hr>
</div>
<?php
}
}
?>
<input class="btn btn-info" type="submit" name="submit_answers"
value="Next">
</form>
THIS IS THE FUNCTION TO CHECK FOR THE ANSWER. THIS IS WHERE IM GETTING THE ERROR FROM. ITS THE $i that's causing the error.
if(isset($_POST['submit_answers'])) {
$result = 0;
$i = 1;
$average = 0;
$item = ($_POST['quizcheck']);
print_r($item) ;
$query = query("SELECT * FROM assess_questions");
confirm($query);
while($row = fetch_array($query)) {
print_r($row['answer_id']);
$checked = ($row['answer_id']) == $item[$i];
if($checked) {
$result++;
}
$i++;
}
}
The clue is in the contents of $item which you have done a print_r on and got the result:
Array(['1'] => 1)
You're getting this result because in your html your radio buttons are labelled quizcheck['n'] where n is the question id. So presumably in this case you have pressed the first radio button in the first question. You should change the line which gives the radio buttons a name to
<input type="radio" name="quizcheck[<?php echo $row['question_id']; ?>]" value=1><?php echo $row['A']; ?><br>
(i.e. remove the single quotes around <?php echo $row['question_id']; ?>). This will make $item look like:
Array ( [1] => 1 )
so the test
($row['answer_id']) == $item[$i];
will work. Note the parentheses around $row['answer_id'] are unnecessary.
The other issue you are going to run into is that your form obviously doesn't require the user to submit an answer to every question. This means that in your while loop you need to check whether the user has submitted an answer to be checked against the result. If you are not going to make it compulsory to answer all questions, you will need to put an array_key_exists check around the result checking code:
if (array_key_exists($i, $item)) {
$checked = $row['answer_id'] == $item[$i];
if ($checked) {
$result++;
}
}
you begin with $i = 1;
in which case you'll avoid $item[0]; (first position) and it will mismatch $checked = ($row['answer_id']).
start with $i=0; as if there's only one answer $i[1] will not exists but $i[0];
****EDIT****
first check your query result for not being void:
example, having this db connection function/method:
<?php
function connection(){
try{
//host, user, passwd, DB name)
$mysqli = new mysqli($host, $user, $passwd, $dbName);
return $mysqli;
}catch (Exception $mysqlin){
echo "Error establishing connection with ddbb ".$mysqlin->getMessage();
}
}
?>
And modifying your code:
if(isset($_POST['submit_answers'])) {
$result = 0;
//indexes must start at 0 unless you ensure that you don't need 0 value and your algorithm will not keep trying to get a value out of bounds / array offset
$i = 0;
$average = 0;
//i assume that $_POST['quizcheck'] is an array, otherwise the $item[$i] will be an out of bounds, which match with your issue (array offset). But i ensured some parts of your structure below for you to learn:
$item = ($_POST['quizcheck']);
print_r($item) ;
//you'll must prepare this statement after, for security
$sql = query("SELECT * FROM assess_questions");
//we get the result of this query on $result, if possible
if($result = connection()->query($sql)){
//we get the first row inside $rs (usually called Record Set) as associative (it means that you'll call the values as the column name on DB unless you use AS "Alias" on your query.
$rs = mysqli_fetch_assoc($result);
//if the record set is not void:
while($rs!="") {
//assuming that your DB col is called answer_id
print_r($rs['answer_id']);
//checked will get the value of matching those two arrays, so make sure you control nullables:
if($checked = ($rs['answer_id']) == $item[$i]){
//only if $checked value could be set
if($checked) {
$result++;
}
}
$i++;
}
//repeat this to get the next value, when it has no more values it will be void so it will escape from while loop.
$rs = mysqli_fetch_assoc($result);
}
}
Never assume that you'll get always a value.
Never assume that users will put numbers in some input only because you told them to do it.
Never use dates without checking.
Never state an algorithm with not-controlled vars/function outputs.
Control all data all over across your code and comment it, it will help you to avoid issues and modify your code months after you coded it.
Hope it helps you.
I recommend you to get a hosting to test/code in a controlled environment.

Create a PHP array from an array from of HTML input values in a for loop

I've trying to create an array that consists of the values of inputs in loops. I am very new to PHP and looked up several other questions but to no avail. I am taking a random number "$QuestionNoSelect" and selecting a text and info from a MySQL server about the question.
//For loop for displaying and naming
for($i = 0; $i < 11; $i++)
{
$QuestionNoSelect = rand(1,16);
array_push($IDListing, $QuestionNoSelect);
$sql = "SELECT QuestionText FROM johnconn_sstest.tbRandomArray WHERE QuestionNo = $QuestionNoSelect";
$QuestionText = $conn->query($sql);
if ($QuestionText->num_rows > 0)
{
// output data of each row
while($row = $QuestionText->fetch_assoc())
{
//Number Question, Increment, Question then input box
echo "<br><br>".$QuestionNumberer. ". ". "<br>";
echo "Question number ID= ".$QuestionNoSelect, "<br>";
$QuestionNumberer++;
echo $row["QuestionText"];
echo '<br>'.'Answer';
echo "<input type='text' name='answerbox[]' id='answerbox[]' class='userInfo' value='".$i."'/>";
echo '<br>'.'comment(if Applicable)';
echo "<input type='text' name='commentbox[]' id='commentbox'[]' class='userInfo' value='".$i."'/>";
}
}
else
{
echo "0 results";
}
}
I am trying to get these values from the array of names or IDs I've created but cannot figure out why I can't get it to work. I cannot even get the array of values to print
//PRINT ANSWER
echo '<br>Answer List <br>';
for($i = 0; $i < 11; $i++)
{
$_POST("answerbox[$i]");
}
Any help would be greatly appreciated. Thank you.
The short answer is that you are treating $_POST like it is a function ($_POST()) instead of an array ($_POST[]). Because your form fields are 1-dimensional arrays, your $_POST data is a 2-dimensional array. Access the submitted array elements using this syntax:
$_POST[formfieldname][numerickey]
I have rewritten a portion of your code and added some refinements which should improve efficiency and show some good practices.
$conn=new mysqli($host, $user, $pass, $dbname);
$conn->select_db('johnconn_sstest'); // designate a default database
$sql="SELECT QuestionNo,QuestionText FROM tbRandomArray ORDER BY RAND() LIMIT 10;"; // until your table gets very, very large RAND() will serve you well
if($result=$conn->query($sql)){ // declare $result and check if true/success or false/syntax failed
$i=0;
echo "<form action=\"receiving_page.php\" method=\"post\">"; // assign receiving page and data delivery method
while($row=$result->fetch_assoc()){ // loop through your db table rows
++$i;
echo "Q$i ID:{$row['QuestionNo']}<br>"; // show counter and question's row id
echo "<input type=\"hidden\" name=\"QNo[$i]\" value=\"{$row['QuestionNo']}\">"; // invisibly pass question id to receiving page
echo "{$row['QuestionText']}<br>";
echo "Answer <input type=\"text\" name=\"answerbox[$i]\" id=\"answerbox$i\" class=\"userInfo\" value=\"\"><br>"; // assign numeric key to each answer input name beginning with 1
echo "Comment(if Applicable) <input type=\"text\" name=\"commentbox[$i]\" id=\"commentbox$i\" class=\"userInfo\" value=\"\"><br><br>"; // assign numeric key to each answer input name beginning with 1
}
echo "<input type=\"submit\" value=\"Submit\">"; // submit button with no name attribute so the value is not passed to the receiving page
echo "</form>";
}else{
echo $conn->error;
}
# receiving_page.php:
if(isset($_POST["QNo"]) && sizeof($_POST["QNo"])==10 &&
isset($_POST["answerbox"]) && sizeof($_POST["answerbox"])==10 &&
isset($_POST["commentbox"]) && sizeof($_POST["commentbox"])==10){
foreach($_POST["QNo"] as $index=>$value){
// do whatever you like with the values, use $index access other arrays' elements
// $value is each QNo in sequence.
// $_POST["answerbox"][$i] is answerbox value in the same QNo row
// $_POST["commentbox"][$i] is commentbox value in the same QNo row
}
}else{
echo "Did not receive the full batch of expected values";
}
Of course, on your form, the fields' keys ($i in fieldname[$i]) can be omitted like this: fieldname[] -- this may be preferable but just be aware that then the numerickeys will start at 0 instead of 1 and will automatically increment.
print_r is your friend. You can print_r($_POST) which will let you see if you have what you think you have. Once you see that it should be clear why you aren't seeing what you want.
If this code is intended to be printing the answers, it needs to be something like
echo $_POST["answerbox[{$i}]"];

How to make a form with that picks questions and saves answers from/into database

I'm making a form that brings questions and answers from the database, i have several questions, but i want to answer one question on each page and then go to the next question. How can i make that possible? i need some tips.
My code for bringing the questions and answers looks like this:
echo "<form method='post'>";
$sql= "SELECT pid, qid, question_link FROM question ORDER BY qid ASC LIMIT 1";
$result = $mysqli->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_array()) {
$pid1= $row['pid'];
$qid1= $row['qid'];
echo $row['question_link']."<br>";
}
}
$sql1= "SELECT pid, qid, aid, answer, points FROM answer_det WHERE pid=$pid1 AND qid=$qid1";
$result1 = $mysqli->query($sql1);
if ($result1->num_rows > 0) {
while($row = $result1->fetch_array()) {
$answer= $row['answer'];
$aid= $row['aid'];
echo "<input type='radio' name='answers' value='".$answer."'/>".$answer."<br>";
}
}
echo "<input type='submit' value='Submit'></form>";
Should i make another PHP page that saves the data into the database and shows the next question? or is there any function that can make that?
depends on the case. If you want the user to stop on the way and maybe come back next time and finish it up, then DB is a good option. else you can use session to store their progress.
<?php
session_start();
if(isset($_POST['name'])){
//store answers in session
$new = (!empty($_SESSION['session_name']))? $_SESSION['session_name'].'|'.$_POST['name'] : $_POST['name'];
//split session into an array
$_SESSION['session_name'] = $new;
}
else if(isset($_POST['clear'])){
if(!empty($_SESSION['session_name'])){
unset($_SESSION['session_name']);
echo "cleared";
}
else
echo "Nothing to Clear";
}
if(!empty($_SESSION['session_name'])){
var_dump($_SESSION['session_name']);
}
//finish the procees here befor storing into database;
//use foreach to itterate btw arrays and match anwers
//$_SESSION['session_name'] = explode('|', $_SESSION['session_name']);
//answer table $answers = array('a','b','c','d','e');
/* foreach($_SESSION['session_name'] as $key => $ans){
if($ans == $answer[$key]){
//right procesesor
}
else{
//wrong procesesor
}
} */
//handle the right and wrong process get to total score the store in db
?>
<form method="post" action="index.php">
<input name="name" type="text" placeholder="">
<input type="submit" value="submit">
</form>
<form method="post" action="index.php">
<input type="submit" name="clear" value="clear">
</form>
SIMPLE BASIC demo of how session can get the job done without querying the db each time.

Getting two variables from one radio button?

http://i.stack.imgur.com/Gy3o0.png
That is what the site looks like now. What I want to do is when you click on the approve registration on the table, it will extract the value of the id no and the name of that particular record. I thought i was on the right track. I knew how to get the id no. But it doesn't get the value of the name at the same time.
This is how the code looks like:
while($row = mysql_fetch_array($mayor))
{
$id = $row['identification_no'];
$name = $row['lastname'].", ".$row['firstname'];
echo "<tr>";
echo "<td><form method=post action=approvedmayor.php><input type='radio' name=id value='$id'></td>";
}
approvedmayor.php
$query = mysql_query("insert into tbcandidates VALUES ($id, '$name', 'mayor')");
if ($query)
{
echo "You appproved ";
echo $name;
}
else
echo "error";
you can try like this...
<?php
while($row = mysql_fetch_array($mayor))
{
$id = $row['identification_no'];
$name = $row['lastname'].", ".$row['firstname'];
echo "<tr><td><a href='approvedmayor.php?id=$id&name=$name'>Approve</a></td></tr>";
}
?>
in this type don't use the form, and Approve button... try this alone
Actually it is bad practice to insert that kind of data directly from POST data.
If you have all these candidates already stored in the database, you should run a SELECT query in your approvedmayor.php first, and if the candidate still exists, insert it's data to another table.
$query = mysql_query('SELECT * FROM `candidates` WHERE `id` = '.$id.' LIMIT 1');
if(mysql_num_rows($query)) {
$candidate = mysql_fetch_assoc($query);
$insertQuery = mysql_query("insert into tbcandidates VALUES ($candidate['id'], $candidate['name'], $candidate['mayor'])");
if ($insertQuery) {
echo "You appproved ";
echo $name;
} else echo "error";
} else echo 'This candidate is no longer available';
I understand your question,
But thats not the best way go ahead, Before we move let us understand some little elements functions
Radio Button : Its an input type element, that allows the user to choose only one [ 1 ] of option given list.
Check Boxes : Its an input type element, that allows the user to select n number of options or selections from give list.
Fore info - http://www.w3schools.com/html/html_forms.asp
Now comming to your question..
You need to modify your code to check boxes as below
<input type='checkbox' name=id[] value='$id'>
Notice : elements name is in Array mode.. ie whenever a user one or more than one, the values are stored in array.
Once the values are stored in array, call it / use if however you want.
For your mentioned code
echo "<form method=post action=approvedmayor.php>';
while($row = mysql_fetch_array($mayor))
{
$id = $row['identification_no'];
$name = $row['lastname'].", ".$row['firstname'];
echo "<tr>";
echo "<td><input type='radio' name=id[] value='$id'></td>";
}
echo "</form>";
approvedmayor.php
$temp_app_arr = $_POST['id'];
foreach ($temp_app_arr as $pos => $val) {
$query = mysql_query("insert into tbcandidates VALUES ('$val', '$name', 'mayor')");
if ($query) {
echo "You appproved ";
echo $name;
} else {
echo "error";
}
}
And i believe this should gonna be good code / algorithm for your project.

Dropdown Menu to Query Database

First of I apologize if this is a dumb question - I'm just starting to pick up my php/mysql skills. I'm making a dropdown form with 3 dropdowns. I want to be able to trigger a query from the form. You select Part Type, Make, Model hit submit and a table of results is displayed.
I have my form populated with 3 arrays and when you hit submit, I can echo the key of each selected item to the page:
echo '<form action="dbBrowse.php" method="post">';
$mak = array (0 => 'Make', 'Ford', 'Freightliner', 'Peterbilt', 'Sterling', 'Mack', 'International', 'Kenworth', 'Volvo');
$mod = array (0 => 'Model', 'Argosy', 'Midliner');
$p = array (0 => 'Part', 'Radiator', 'Charge Air Cooler', 'AC');
echo '<select name="drop1">';
foreach ($p as $key => $value) {
echo "<option value=\"$key\">
$value</option>\n";
}
echo '</select>';
echo '<select name="drop2">';
foreach ($mak as $key => $value) {
echo "<option value=\"$key\">
$value</option>\n";
}
echo '<select/>';
echo '<select name="drop3">';
foreach ($mod as $key => $value) {
echo "<option value=\"$key\">
$value</option>\n";
}
echo '<select/>';
echo '</form>';
//echo keys of selection
echo $_POST['drop1'];
echo "<br />";
echo $_POST['drop2'];
echo "<br />";
echo $_POST['drop3'];
//these echo something like 1, 1, 3 etc. to my page
Where I'm getting lost is I'm looking to take the selected options and insert them into a query something like this:
$dropSearch = mysql_query('SELECT * FROM parts WHERE part= "$partTypeVar" . AND WHERE make = "$makeTypeVar" . AND WHERE model = "$modelTypeVar"');
$partTypeVar being the corresponding value to the key that is being returned from the array.
I'm driving myself crazy trying to figure out how to make that happen. Eventually I want to expand this further but just being able to create a mysql statement with the values selected would make my day right now. I understand the concept of what needs to happen but I'm unsure of how to accomplish it. Any help or pushes in the right direction would be greatly appreciated.
First of all, you have to delete the . char in your SQL query, there's no need to use it for now and of course assign the correct values to the variables.
$partTypeVar = mysql_real_escape_string($_POST['$drop1']);
$makeTypeVar = mysql_real_escape_string($_POST['$drop2']);
$modelTypeVar = mysql_real_escape_string($_POST['$drop3']);
$dropSearch = mysql_query('SELECT * FROM parts WHERE part= "$partTypeVar" AND WHERE make = "$makeTypeVar" AND WHERE model = "$modelTypeVar"');
I am assuming that's the correct order of your variables.
I hope this help!
If I've understood your question, when the form is submitted, you want to query the database with the selected values.
Example using AND:
// Prepare the Query
$query = sprintf(
"SELECT * FROM parts WHERE part='%s' AND make='%s' AND model='%s'",
mysql_real_escape_string($_POST['drop1']),
mysql_real_escape_string($_POST['drop2']),
mysql_real_escape_string($_POST['drop3'])
);
// Execute the Query
mysql_query($query);
This will select all rows from the table parts that match those three values.
Example using OR:
// Prepare the Query
$query = sprintf(
"SELECT * FROM parts WHERE part='%s' OR make='%s' OR model='%s'",
mysql_real_escape_string($_POST['drop1']),
mysql_real_escape_string($_POST['drop2']),
mysql_real_escape_string($_POST['drop3'])
);
// Execute the Query
mysql_query($query);
This will select all rows from the table parts that match any of those three values.
You can read more about this:
mysql_query
mysql_real_escape_string
MySQL 5.6 Reference Manual :: 12 Functions and Operators :: 12.3 Operators
<select name="myFilter">
<option value="Chooseafilter" name="default">Choose a filter...</option>
<option value ="Lastname" name="opLastName">Last Name</option>
<option value="Firstname" name="opFirstName">First Name</option>
<select>
<li><!--TEXT SEARCH INPUT--><input type="text" name="search_filter" /></li>
...
dbconnection();#assume that all connection data is here
...
$filter = $_POST['myFilter']; #
...
switch($filter)
{
case "Lastname":
$selectedoption = "profile_name";
break;
case "Firstname":
$selectedoption="profile_first_name";
break;
case "Chooseafilter":
$selectedoption = "";
break;
}
$result = pg_query($db_con, "SELECT * FROM profile WHERE ".$selectedoption." LIKE'%$_POST[search_filter]%'");
$row = pg_fetch_assoc($result);
if (isset($_POST['submit']))
{
while($row = pg_fetch_assoc($result))
{
echo"<ul>
<form name='update' action='' method='POST'>
<li>Guest Last Name:</li>
<li><input type='text' name='profile_name_result' value='$row[profile_name]' /></li>
<li>Guest First Name:</li>
<li><input type='text' name='profile_first_name_result' value='$row[profile_first_name]' /></li>
<li><input type='submit' value='Update' name='update'></input></li>
...

Categories