HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

Recording user response times for a quiz

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
userresponsequizforrecordingtimes

Problem

I am working on a simple quiz-type game in which the user basically is asked a series of questions and needs to provide an answer.

I'm trying to find a solid/robust way of recording how long it takes for the user to answer each question. This is a web-based game so I am using JavaScript and PHP. I am very inexperienced, so I suspect this is not the best way to do it; at least I hope it's not because it seems very weak. I would appreciate any suggestions as to how to go about making a more full-proof solution. It's not critical that the time be accurate to the millisecond I'm just looking to build something that will be consistent and accurate to within a second or two.

The reason I'm doing it like this rather than just recording the time in the browser is because, as I understand it, the data could theoretically be altered by the user. This is also why I don't send that correct and answers to the browser until the user provides an answer.

Here is my current approach:

```

diff($endDTO);
$timeTaken = $timeDiff->format('%s');

return $timeTaken;
}

date_default_timezone_set("UTC");

if($_SERVER['REQUEST_METHOD'] === 'POST')
{
if(
isset($_POST['user_answer']) &&
isset($_SESSION['app_index'])
)
{
$index = $_SESSION['app_index'];///current question in the game
$len = count($_SESSION['words']);///number of questions in the game
$userAns = $_POST['user_answer'];
$rightAns = $_SESSION['right_answers'];

if(isset($_SESSION['app_start']))////if this is the first question
{
$responseTime = getTimeTaken($_SESSION['app_start']);
unset($_SESSION['app_start']);
$_SESSION['question_start'] = new DateTime('NOW');
}
else if(isset($_SESSION['question_start']))///not the first question
{
$responseTime = getTimeTaken($_SESSION['question_start']);
$_SESSION['question_start'] = new DateTime('NOW');
}

Solution

Just some simple stuff,
a common.php file for common code used by both files. DRY don't repeat yourself.

Writing a script like you have is fine, the points i have noted will help you if you come back to maintain it in a year or so, and have forgotten how it works.

The bulk of programming jobs are about maintaining a code base, not creating new stuff, so if you can learn how to make maintenance easier, it will be beneficial for you in the long run. (I wish i had learnt this stuff much earlier on)

I have added inline comments explaining the changes i made


diff($endDTO);
    $timeTaken  = $timeDiff->format('%s');

    return $timeTaken;
}

function is_first_question() {
    return isset($_SESSION['app_start']);
}

function is_question_started() {
    return isset($_SESSION['question_start'];
}

//
function mark_user_answer($user_answer, $correct_answer) {
    return ($user_answer == $correct_answer) ? 1 : 0;
}

function move_to_next_question() {
    $_SESSION['app_index']++;
}

function start_question_timer() {
    $_SESSION['question_start'] = new DateTime('NOW');}
}

?>

Code Snippets

<?php
/* common.php */
require 'classes/Database.php';

session_start();
date_default_timezone_set("UTC");

?>



<?php
/* get_game_data.php
 *
 * user clicks button to start game
 * and triggers ajax request sent to this file
 */

require 'common.php';

// moved into common.php
// session_start();

if($_SERVER['REQUEST_METHOD'] === 'GET')
{
    if(isset($_GET['gamesettings'])){///check certian user defined game options are set

        // moved into common.php
//        require 'classes/Database.php';

        // moved into common.php
//        date_default_timezone_set("UTC");

        $_SESSION['app_start'] = new DateTime('NOW');////store time at which game/first question starts
        $_SESSION['app_index'] = 0;

        // warning if $_GET['app'] not set this will get a warning notice, we can never trust GET/POST data
        // if($_GET['app'] === 'aural') {
        if(isset($_GET['app']) && $_GET['app'] === 'aural') {

            $db = new Database();

            $gameData = getGameData($db);///just an example
            //etc...
            //query database for game data, i.e. the questions,

            // i prefer to do my internal logic before i output data. this way if something fails i can handle it prior to responding to the user
            $_SESSION['right_answers'] = $gameData['answers'];///store the right answers to varify against user answers later

            echo json_encode($gameData['questions']);//then send back to browser



        }

    }
}
?>



<?php
/* post_game_data.php
 *
 * user answers question in a textbox etc.
 * then clicks a submit button which posts the answer to
 * this file via ajax again
 */

require 'common.php';

// moved into common.php
//session_start();




// moved into common.php
// date_default_timezone_set("UTC");

if($_SERVER['REQUEST_METHOD'] === 'POST')
{
    // what you have done is not bad, i just prefer to have all user supplied data handled in one place, POST/GET
    // so i know that everything beyond here has been sanitized
//    if(
//       isset($_POST['user_answer']) &&
//       isset($_SESSION['app_index'])
//    )

    $userAns = isset($_POST['user_answer']) ? $_POST['user_answer'] : null;

    // good variable names can also help reduce the need for comments
    // which of these two following variable names are easier to understand

    // $index = $_SESSION['app_index'];///current question in the game
    $current_question_index = isset($_SESSION['app_index']) ? $_SESSION['app_index'] : null;

    if($userAns != null && $current_question_index != null)
    {

        // same here with variable naming
        // if you are going to maintain these scripts over time, you need to make it easier to remember what is going on

        // $len = count($_SESSION['words']);///number of questions in the game
        $num_questions = count($_SESSION['words']);

        // handled above, no need to repeat
        //      $userAns = $_POST['user_answer'];

        $rightAns = $_SESSION[

Context

StackExchange Code Review Q#39593, answer score: 2

Revisions (0)

No revisions yet.