0

I am making a web-application for Quiz competition. For the purpose, I wrote a php script which is processed by the same page. Now when I am adding scores and question numbers, the score is incremented or remain unchanged depending upon the previous answer if someone is refreshing the page. Now I googled the problem and found something like PRG.But this method works if the page is processed by other page (What I think ). Again, a friend of mine told me to use Javascript. But what if someone has turned Js off? Can't we have a solution in php itself. I tried session method also, but I did not fix the issue . Please help me .

PHP Quiz script is here:

<?php 

    // starting session
    session_start();
    if (!isset($_SESSION['user_id'])) {
    echo '<p class="login">Please <a href="login.php">log in</a> to access this page.</p>';
    exit();
  }
  else {
    echo('<p class="login">You are logged in as ' . $_SESSION['username'] . '. <a href="logout.php">Log out</a>.</p>');
  }
     // $query = ;
  //this get is taking level from index.php

    if ( isset($_GET['level']))
    {
        $level = $_GET['level'];
    }       

    else
    {
        $level = 'E';
    }

    //connecting to Data Base
    require_once('connectvars.php');
    $dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);

    if (isset($_POST['submit']))
    {
        $level = $_POST['level'];
        // $_SESSION['flag']
        $answer = $_POST['answer'];
        if ( !empty($answer))
        {

            $qid = $_POST['qid'];
            $select = $_POST['select'];
            $user_id = $_SESSION['user_id'];

            $result = mysqli_query($dbc,"select * from question where qid = '$qid'")
            or die("Error in connection.");

            $row = mysqli_fetch_array($result);

            if ( $row['ANSWER'] == $answer)
            {
                echo 'Your answer is correct.';
                mysqli_query($dbc,"insert into user_question ( qid,user_id,answer_key) values ( '$select','$user_id',1)")
                or die ("Error in updating values in user_question");

            }
            else
            {
                echo 'Your answer is incorrect.';
                mysqli_query($dbc,"insert into user_question ( qid,user_id,answer_key) values ( '$select','$user_id',0)")
                or die ("Error in updating values in user_question");           
            }
            $answer = "";
        }
        else
        {
            echo 'You did not answer the previous question';
        }



    }


        $user_id = $_SESSION['user_id'];
        // $dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);

        //Taking a random value from the list of question
        $id_list = array();
        // echo $user_id;
        // echo $level;
        $result = mysqli_query($dbc,"select * from question where lvl = '$level' and user_id != '$user_id' and qid not in ( select qid from user_question where user_id = '$user_id' )");
        while ( ($row = mysqli_fetch_array($result)) )
        {
            if ( $row['user_id'] != $user_id)
            array_push($id_list,$row['qid']);
        }
        // print_r($id_list);
        //Whether user viewed all the questions
        if ( empty($id_list))
        {
            echo 'Great, You have visited all the question, wait for more update ';
            echo '<br>';
             echo '&#10084; <a href="view_score.php">View Your Score</a><br />';
            exit();
        }
        // Taking a random value after shuffling it

        shuffle($id_list);
        $select = $id_list[array_rand($id_list)];



        $result = mysqli_query($dbc,"select * from question where qid='$select'");

        // Showing the question
        while ( ($row = mysqli_fetch_array($result)) )
        {
            ?>
            <!DOCTYPE html>
            <html>
            <head>
                <title></title>
            </head>
            <body>
                <h3> <?php echo $row['sawal']; ?></h3>

                    <form  method = "POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">

                        <input type="radio"  name=" answer" value="A" ><?php echo $row['a']; ?><br>
                        <input type="radio"  name=" answer" value="B" ><?php echo $row['b']; ?><br>
                        <input type="radio"  name=" answer" value="C" ><?php echo $row['c']; ?><br>
                        <input type="radio"  name=" answer" value="D" ><?php echo $row['d']; ?><br>

                        <input type="hidden" name = "qid" value="<?php echo $row['qid'] ?>">
                     <!--    <input type="hidden" name = "range" value="<?php  $range ?>"> -->
                        <input type="hidden" name = "level" value="<?php  echo $level ?>">
                        <input type="hidden" name = "select" value="<?php  echo $select ?>">

                        <input type="submit" name="submit" value="ANSWER"/>

                    </form>

            </body>
            </html>
        <?php
        require_once('view_score.php');
    }


 ?>

Edit:

I changed my code as Mat is suggested. But it is not allowing me to have different question from the table?

The revised php code is here:

<?php 

// starting session
session_start();


  if (!isset($_SESSION['user_id'])) {
    echo '<p class="login">Please <a href="login.php">log in</a> to access this page.</p>';
    exit();
  }
  else {
    echo('<p class="login">You are logged in as ' . $_SESSION['username'] . '. <a href="logout.php">Log out</a>.</p>');
  }
     // $query = ;
  //this get is taking level from index.php

    if ( isset($_GET['level']))

{
    $level = $_GET['level'];
}       

else
{
    $level = 'E';
}

//connecting to Data Base
require_once('connectvars.php');
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);

if (isset($_POST['submit']))
{



$is_new_post = true;
if (isset($_SESSION["myform_key"]) && isset($_POST["myform_key"]))
 { 

  if($_POST["myform_key"] == $_SESSION["myform_key"] ){
    $is_new_post = false;
  } 
}
 if($is_new_post){

  $_SESSION["myform_key"] = $_POST["myform_key"];




    $level = $_POST['level'];
    // $_SESSION['flag']
    $answer = $_POST['answer'];
    if ( !empty($answer))
    {

        $qid = $_POST['qid'];
        $select = $_POST['select'];
        $user_id = $_SESSION['user_id'];

        $result = mysqli_query($dbc,"select * from question where qid = '$qid'")
        or die("Error in connection.");

        $row = mysqli_fetch_array($result);

        if ( $row['ANSWER'] == $answer)
        {
            echo 'Your answer is correct.';
            mysqli_query($dbc,"insert into user_question ( qid,user_id,answer_key) values ( '$select','$user_id',1)")
            or die ("Error in updating values in user_question");

        }
        else
        {
            echo 'Your answer is incorrect.';
            mysqli_query($dbc,"insert into user_question ( qid,user_id,answer_key) values ( '$select','$user_id',0)")
            or die ("Error in updating values in user_question");           
        }
        $answer = "";
    }
    else
    {
        echo 'You did not answer the previous question';
    }

        }

}


    $user_id = $_SESSION['user_id'];
    // $dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);

    //Taking a random value from the list of question
    $id_list = array();
    // echo $user_id;
    // echo $level;
    $result = mysqli_query($dbc,"select * from question where lvl = '$level' and user_id != '$user_id' and qid not in ( select qid from user_question where user_id = '$user_id' )");
    while ( ($row = mysqli_fetch_array($result)) )
    {
        if ( $row['user_id'] != $user_id)
        array_push($id_list,$row['qid']);
    }
    // print_r($id_list);
    //Whether user viewed all the questions
    if ( empty($id_list))
    {
        echo 'Great, You have visited all the question, wait for more update ';
        echo '<br>';
         echo '&#10084; <a href="view_score.php">View Your Score</a><br />';
        exit();
    }
    // Taking a random value after shuffling it

    shuffle($id_list);
    $select = $id_list[array_rand($id_list)];



    $result = mysqli_query($dbc,"select * from question where qid='$select'");

    // Showing the question
    while ( ($row = mysqli_fetch_array($result)) )
    {
        ?>
        <!DOCTYPE html>
        <html>
        <head>
            <title></title>
        </head>
        <body>
            <h3> <?php echo $row['sawal']; ?></h3>

                <form  method = "POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">

                    <input type="radio"  name=" answer" value="A" ><?php echo $row['a']; ?><br>
                    <input type="radio"  name=" answer" value="B" ><?php echo $row['b']; ?><br>
                    <input type="radio"  name=" answer" value="C" ><?php echo $row['c']; ?><br>
                    <input type="radio"  name=" answer" value="D" ><?php echo $row['d']; ?><br>

                    <input type="hidden" name = "qid" value="<?php echo $row['qid'] ?>">
                 <!--    <input type="hidden" name = "range" value="<?php  $range ?>"> -->
                    <input type="hidden" name = "level" value="<?php  echo $level ?>">
                    <input type="hidden" name = "select" value="<?php  echo $select ?>">
                     <input type="hidden" name="myform_key" value="<?php echo md5("CrazyFrogBros"); ?>" />

                    <input type="submit" name="submit" value="ANSWER"/>

                </form>

        </body>
        </html>
    <?php
    require_once('view_score.php');
}

?>

Community
  • 1
  • 1
user3641971
  • 137
  • 1
  • 7
  • PRG is the right solution. – Quentin Aug 16 '14 at 21:35
  • So I have to use a different page to solve it. – user3641971 Aug 16 '14 at 21:37
  • 3
    (1), no, that 'PRG' works perfectly well for the same page, as long as you only _do_ something on POST, which you seem to do. It is perfectly valid for a URL to redirect to itself (2) that would work against F5 / /refresh doubles. Accidental double-clicks might still occur, if those are a problem, google for "nonce"s. – Wrikken Aug 16 '14 at 21:37
  • @Wrikken Please help me by some code in the page, illustrating PRG. – user3641971 Aug 16 '14 at 21:42
  • @user3641971 See this http://en.wikipedia.org/wiki/Post/Redirect/Get and this http://stackoverflow.com/questions/4142809/simple-post-redirect-get-code-example – Rahil Wazir Aug 16 '14 at 21:45
  • You can use a nonce. Edit: *Ah*, just noticed Wrikken's comment. *Well, there ya go.* – Funk Forty Niner Aug 16 '14 at 21:46
  • Off-topic, but I should note that your script is vulnerable to SQL injections. – ePirat Aug 16 '14 at 21:47
  • ePirat Thanks for pointing it out, I will consider it later, Can you let me know where are these vulnerabilities? – user3641971 Aug 16 '14 at 21:53
  • I'll answer that; your **entire** code is open to [**SQL injection**](http://stackoverflow.com/q/60174/). Use [**prepared statements**](http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php), or [**PDO with prepared statements**](http://php.net/pdo.prepared-statements). – Funk Forty Niner Aug 16 '14 at 22:53
  • @Fred-ii- I would like to suggest OP to read my post about SQL injection: http://stackoverflow.com/questions/25174599/secure-my-php-code-for-login-registration-codes/25174702#25174702 – Krupal Shah Aug 17 '14 at 08:27

1 Answers1

0

I tried session method also, but I did not fix the issue

I don't know how you code it but you can try this: 1. Set a session token with unique hash value e.g.

$_SESSION['formtoken'] = sha1(uniqid('', true));
  1. include it in your form (input hidden) value = $_SESSION['formtoken']
  2. everytime the user submit the form reset the $_SESSION['formtoken'] value
MaT
  • 41
  • 3