Managing Values in PHP Quiz

I want to create a quiz. I bought a pretty cool commercial quiz, but it’s written in JavaScript, which is too hard to understand and work with. So I want to try and do something similar with PHP and jQuery.

The questions and answers are stored in a database, and the HTML looks something like this:

<ul class="UL1">
  <li class="A">one</li>
  <li class="B">two</li>
</ul>
<ul class="UL2">
  <li class="A">red</li>
  <li class="B">blue</li>
</ul>

Ideally, I’d like each list item to look like a button, with no radio button. In other words, I’d like to select and pass values without using a form, if that’s doable.

So let’s suppose someone chooses the first answer (“one”) to the first question. How could I “record” and pass that value on, so, for example, I could display the text “You chose one.”?

I read a simple PHP quiz tutorial that uses the following script to grade the results. I think it ought to work with the quiz I’m working on, but I’m not sure how to modify my code and pass on values. Is this something I’d be better off doing with jQuery, rather than PHP?

            $answer1 = $_POST['question-1-answers'];
            $answer2 = $_POST['question-2-answers'];
            $answer3 = $_POST['question-3-answers'];
            $answer4 = $_POST['question-4-answers'];
            $answer5 = $_POST['question-5-answers'];
        
            $totalCorrect = 0;
            
            if ($answer1 == "B") { $totalCorrect++; }
            if ($answer2 == "A") { $totalCorrect++; }
            if ($answer3 == "C") { $totalCorrect++; }
            if ($answer4 == "D") { $totalCorrect++; }
            if ($answer5) { $totalCorrect++; }
            
            echo "<div id='results'>$totalCorrect / 5 correct</div>";

Thanks.

Store the values in json and. Use a data attribute on each item. Then register a method to run on click to get that attributes value. Then us ajax to send it to the server to be stored in the database. Your going to need to create a div to serve at a button to perform the ajax request.

OK, I’ll start doing my homework on JSON and data attributes. Thanks for the tip. :wink:

Yeah, the front ends going to need to be jquery. Send the data to the server as json and send the data back as json. You could use angularjs too and cut jquery out of it.

jQuery is a Javascript framework that runs on the client(browser), which makes the code and the answers readable by the user. Pass an array to PHP in the JSON format. Read the array in PHP using the function ‘json_decode’.

Honestly, you’re better off actually using radios and hiding the input fields than trying to get non-form elements to behave like ones and introducing all sorts of craziness. You can always style the fields to look however you want once you get it working.

Here’s a simple example:

<form action="quiz.php">
    <!-- Question 1 -->
    <fieldset>
        Question:
        <label>Answer 1 <input type="radio" value="a" name="question-1"></label>
        <label>Answer 2 <input type="radio" value="b" name="question-1"></label>
        <label>Answer 3 <input type="radio" value="c" name="question-1"></label>
        <label>Answer 4 <input type="radio" value="d" name="question-1"></label>
    </fieldset>
</form>

Then:

$(function(){

    // Trap the form submit event
    $('form').submit(function(e){
        e.preventDefault() // Prevent browser refresh
        var answers = $(this).seralize()

        // Manually send the data with AJAX
        $.post({
            url: $(this).attr('action')
            data: answers,

            // Stuff to do after we get a response
            success: function(response){
                $('#results').text(response.correct)
            }
        })
    })
})

That’s really all there is too it. Then on the server:

<?php 
$answer1 = $_POST['answers-1'];
$answer2 = $_POST['answers-2'];
$answer3 = $_POST['answers-3'];
$answer4 = $_POST['answers-4'];
$answer5 = $_POST['answers-5'];
$totalCorrect = 0;
if ($answer1 == "B") { $totalCorrect++; }
if ($answer2 == "A") { $totalCorrect++; }
if ($answer3 == "C") { $totalCorrect++; }
if ($answer4 == "D") { $totalCorrect++; }
if ($answer5) { $totalCorrect++; }

// Send the data back as JSON
die json_encode(array(
    'correct'    => $totalCorrect;
));

Awesome labofoz! I’ll give that a try right now. Thanks. :wink:

I have a couple questions about syntax…

The form is self-explanatory, and I wrapped the next section in a script tag - [script]. I added a comma at the end of one line to kill an error message.

<script>
$(function(){

    // Trap the form submit event
    $('form').submit(function(e){
        e.preventDefault() // Prevent browser refresh
        var answers = $(this).seralize()

        // Manually send the data with AJAX
        $.post({
			// I killed an error by adding a comma at the end of the line below.
            url: $(this).attr('action'),
            data: answers,

            // Stuff to do after we get a response
            success: function(response){
                $('#results').text(response.correct)
            }
        })
    })
})
</script>

Then there’s the PHP section…

<?php 
// That's really all there is to it. Then on the server:
$answer1 = $_POST['answers-1'];
$answer2 = $_POST['answers-2'];
$answer3 = $_POST['answers-3'];
$answer4 = $_POST['answers-4'];
$answer5 = $_POST['answers-5'];
$totalCorrect = 0;
if ($answer1 == "B") { $totalCorrect++; }
if ($answer2 == "A") { $totalCorrect++; }
if ($answer3 == "C") { $totalCorrect++; }
if ($answer4 == "D") { $totalCorrect++; }
if ($answer5) { $totalCorrect++; }
?>

But I get an error message here. Is the remainder supposed to be inside the PHP code, too? If I put it there, I still get an error message.

die json_encode(array(
    'correct'    => $totalCorrect;
));

Thanks.

Whoops that’s my bad! There shouldn’t be a semicolon after $totalCorrect

OK, I fixed that, but I still have some kind of error between these two lines:

if ($answer5) { $totalCorrect++; }
?>

die json_encode(array(

Do I have to wrap the last code (beginning with die json_encode) in some sort of tags? I’ve tried PHP, JS tags, etc.

Your checking to see if that variable exist/has a value. You need to perform a comparison in the if statement.

Sorry, I don’t follow what you’re saying. Are you saying the PHP script that ends with if ($answer5) { $totalCorrect++; } is unfinished because I have to add a comparison?

Yes.

If( $answer5 == ‘Some value’ )
{
// do something here
}

Your code is doing a boolean test not a comparison test. By boolean I mean checking to see if the variable exists or has a value not comparing the value of the variable against another value. Your form should only be submitting one questions answer at a time. Then test that against the correct answer to determine if it’s correct. If more than one answer is allowed loop through them and perform a comparison and use a counter to determine the number of correct.

$correct = 0;

foreach( $_POST[‘answers’] as $answer )
{
if( $answer == $data_here )
{
$correct++;
}
}

Yes, unless $answer5 is a freebie where any answer is considered correct there should be more in that conditional

The other part should be something like

$json = json_encode( $data ) or die( " error msg here" );

Data can be an array or object.

OK, it’s coming into sharper focus now. Plus I discovered a syntax error of my own creation. :wink:

I would rewrite that part like so:

$totalCorrect = 0;
$answers = [1 => 'B', 2 => 'A', 3 => 'C', 4 => 'D', 5 => 'A'];
foreach ($answers as $num => $answer)
{
    $key = 'answer-'.$num;
    if (isset($_POST[$key]) && $_POST[$key] === $answer)
    {
        $totalCorrect++;
    }
}

for the following reasons

  1. It scales a better; if you add another question all you have to do is add it to $answers and you’re done. It also doesn’t grow linearly with the number of answers. If you have 100 questions the main code is still just as long, only $answers will grow big.
  2. It checks if the answer actually exists in $_POST.

PS. the [1 => ‘B’] etc syntax is PHP 5.4+. If you’re on an older version it should be array(1 => ‘B’) etc

2 Likes

Thanks, that looks much better.

However, after changing my code, it says I got 0 right, even if answered everything correctly. I thought maybe the problem was in my fill-in-the-blank question (2 = ‘Jupiter’) or question 10. which requires users to check more than one check box. But I changed both of those values to A, and I got the same result - 0 right.

Do you see a mistake in my code?

$totalCorrect = 0;
$answers = [1 => 'A', 2 => 'Jupiter', 3 => 'C', 4 => 'D', 5 => 'A', 6 => 'C', 7 => 'C', 8 => 'B', 9 => 'B', 10 => 'AA', 11 => 'A'];
foreach ($answers as $num => $answer)
{
    $key = 'answer-'.$num;
    if (isset($_POST[$key]) && $_POST[$key] === $answer)
    {
        $totalCorrect++;
    }
}

Are you still using “answers”

$answer1 = $_POST['answers-1'];

OR “answer”

$key = 'answer-'.$num;

Good point; I think you fixed it. :wink: