Score users' answers to a quiz. No settings file or answer key is used; all data is stored in the calling web page (which you create).
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


scorequiz.php is a simple script for scoring a user's responses to a multiple-choice quiz. No separate settings file or answer key is used; all data is stored in the calling web page.

One advantage of the lack of settings files is that you can call the script even if you don't have access to the server where the script runs. (Measures are taken to prevent cross-site scripting attacks.)

Because all data is stored in the web page, you should not use this script in an academic setting, or any other setting where cheating is unacceptable. Anyone with a passing knowledge of HTML could easily discern the correct answers.

The script displays the user's score in a minimal web page, with short messages that you can configure using the parameters described below. If you prefer, you can use AJAX to fetch and display the score without leaving the page that your script is on. To learn more, read about the async parameter.

If you don't use AJAX, then because all of the data must be passed to the script every time, it is recommended that you submit the form via the POST method, rather than GET. It's true that GET is usually recommended for "idempotent" requests (i.e. those that don't have side effects like causing data to be updated on the server). However, in this case, the GET parameter string, in addition to being long and ugly, would expose the quiz's settings and point values to the user. POSTing the data instead will mitigate that problem.

See quiz.html for a couple of example quizzes.


Each question should have a set of answers as radio-button inputs, which build an array named 'q'.

The inputs' NAME attributes must be the format q[number]. Each answer to a given question must use the same number, and each question must use a different number.

The inputs' VALUE attributes specify how many points each answer is worth.


<li>True or false: The first president of the United States was George Washington.
  <br><input type="radio" name="q[3]" value="1">True
  <br><input type="radio" name="q[3]" value="0">False

<li>True or false: The second president of the United States was George Wendt.
  <br><input type="radio" name="q[4]" value="0">True
  <br><input type="radio" name="q[4]" value="1">False

The question numbers don't have to be in order. (Technically, they don't even have to be numbers.)

0 points for a wrong answer and 1 point for a correct answer is a sensible system. But you can use another arrangement if you want to be able to give partial credit, or if you want some questions to be worth more than others.

You could use drop-down lists instead of radio buttons for the answers. But radio buttons are probably the better user interface for this purpose. The script isn't designed to support checkboxes.


Other settings should be sent as hidden input fields. Their names and functions are as follows.


<input type="hidden" name="maxscore" value="9">

Indicates the maximum possible score that the user could earn, necessary if you want to express the answer as a percentage or proportion. The upside of having to enter this yourself is that you could deliberately enter a lower number than the true maximum if you want the user to be able to score over 100%.


<input type="hidden" name="mustanswer" value="9">

Indicates the minimum number of questions that the user must answer. The script will return an error message if the user answers fewer questions.

Note that this has nothing to do with how many points the user earns, and also that there is no way to specify which questions the user must answer, only how many. (You could do client-side validation with JavaScript if you want to require answers to specific questions.)

If you don't set this, it will default to 0.


<input type="hidden" name="express" value="percentage">

Specify how you want the user's score to be expressed. Recognized values are percentage (rounded to the nearest whole number, e.g. 67%), proportion (as a fraction of maxscore, e.g. 6/9), and total (just the number of points, with no other context, e.g. 6). percentage is the default.


<input type="hidden" name="async" value="1">

Set async to 1 if you're calling the script asynchronously, e.g. using AJAX. The script will only return a short text string containing the user's score (formatted according to the express parameter). Writing the AJAX code that handles this is up to you. If you use async, the parameters scoremsg, upto, retry, and done are irrelevant and can be omitted.

Notwithstanding the example code above, you'll probably want to add async=1 to the URL via JavaScript rather than actually including it in the form.


<input type="hidden" name="scoremsg[0]" value="You got">
<input type="hidden" name="scoremsg[1]" value="correct.">

Use this to customize the message that tells the user their score. It's a two-element array, with part [0] appearing before the score and part [1] appearing after it. Or you can send a single scoremsg parameter, which will be treated as scoremsg[0].


<input type="hidden" name="upto[4]" value="You got most of the answers wrong. Study harder!">
<input type="hidden" name="upto[9]" value="You're well-educated! You got most of the answers right.">

upto is an array of messages that will be displayed based on how well the user did. The above example assumes a maximum score of 9. If the user gets anything up to 4 points, they'll see the first message. If they get 5 - 9 points, they'll see the second message instead.


<input type="hidden" name="retry" value="I must have misclicked something. Let me try again.">

Customize the text of the link that takes the user back to the quiz.


<input type="hidden" name="done" value="I'm done; take me to the home page.">

Customize the text of the link that takes the user to the site's home page.

Off-site requests

There is one setting that must be changed in the PHP file itself. If you're running the script on your own server and don't want to let people use it with quizzes on other servers, uncomment (by deleting the leading # characters) the three lines near the top of the file, under the comment "Disallow requests based on HTTP referrer". Doing this may provide some extra protection against cross-site scripting attacks, and/or discourage people from sending a lot of traffic to your server. However, this measure may not always work, since a browser's HTTP referrer can be omitted or even spoofed.