J. Doe J. Doe - 2 months ago 4
PHP Question

Reasons why a cookie could be resetting?

I am trying to check if a user has taken a quiz before and if he/she has, I want them to be not able to take the quiz again. I implemented the code to do this by using cookies and for some reason my code refuses to stop a user from taking the quiz again. I've been staring at this for a very long time now so help would be nice!

Notes: $_SESSION["index"] is set to 0 initially from a previous page and $_COOKIE['quizTakers"] is an empty array initially. Each Question comes one at a time.

<?php
session_start();
#get array of quizTakers from cookie
$addUser = unserialize($_COOKIE['quizTakers']);
$userN = $_SESSION['username'];

#check if user has taken quiz already and make sure you only check once and not after every question submit
if(count($addUser) != 0 && intval($_SESSION["index"]) == 0 ){
foreach ($addUser as $user) {
if( strcmp($userN,$user) ){
echo "You already took the quiz! <br \>";
echo "<form action=\"changeUser.php\" method=\"post\"> Go Back: <input type=\"submit\"><br \> </form>";
exit();
}
}
array_push($addUser, $userN);
setcookie('quizTakers', serialize($addUser), time()+86400);
echo "loop was entered <br />";
}
#if array is empty(this is should execute the every first time someone takes the quiz
elseif (count($addUser) == 0) {
#add user to array if this is first person taking a quiz yo
array_push($addUser, $userN);
setcookie('quizTakers', serialize($addUser), time()+86400);
echo "cookie added line 29 <br/>";
}

$indexTemp = intVal($_SESSION["index"]);

if(isset($_SESSION["notFirstIndex"])){
#get array of correct answers
$correctAns = $_SESSION["correctAnswers"];
#get particular answer at current index
$currentCorrectAns = intval($correctAns[$indexTemp]) +1;


$userAns = intval($_POST['ans']);
echo "The User picked: ".$userAns." and the correct Answer was: ".$currentCorrectAns."<br/>";

if($userAns == intVal($currentCorrectAns)){
echo " you were correct! <br />";
$_SESSION["totalCorrect"] += 1;
}

else{
echo "you were wrong";
$_SESSION["totalIncorrect"] +=1;
}

}
elseif(!isset($_SESSION['notFirstIndex'])){
echo "Welcome to your quiz, $userN <br />";
echo "You havent answered any questions yet! <br />";

}

?>
<!DOCTYPE html>
<html>
<HR>
</html>

<?php


#When questions are over show results
if($_SESSION["numQuestions"] == $indexTemp){
$_SESSION["index"] = 0;
echo "Your Results are: <br /> ";
echo "Total Questions: ".$_SESSION["numQuestions"]."<br/>";
echo "Total Correct: ".$_SESSION["totalCorrect"]."<br/>";
echo "Total Incorrect: ".$_SESSION["totalIncorrect"]."<br/>";
$percentage = (intval($_SESSION["totalCorrect"]) / intval($_SESSION["numQuestions"])) * 100 ;
echo "Percentage Rightht: $percentage % <br/ >";
echo "<form action=\"process.php\" method=\"post\"> Back to Main screen: <input type=\"submit\"><br \> </form>";

$takers = unserialize($_COOKIE['quizTakers']);
echo $takers[0];
if(count($takers) == 1){
echo "<br />";
echo "You were the first Quiz Taker: <br />";
echo "Total Takers: 1 <br />";
echo "Number Right: ".$_SESSION["totalCorrect"]."<br/>";
echo "Number Incorrect: ".$_SESSION["totalIncorrect"]."<br/>";
echo "Average: $percentage % <br/ >";
exit();
}

exit();
}

$filename = $_SESSION["quizOfTheDay"];

$quizStuff = file($filename);
$ctr =1;


$questionInfo = $quizStuff[$indexTemp];

$questionParse = explode("#", $questionInfo);
#$_SESSION["correctAns"] = $questionParse[2];
#echo $_SESSION["correctAns"]." from line 56 <br />";
$_SESSION['notFirstIndex'] = "true";
$answerChoices = explode(":",$questionParse[1]);

echo "$questionParse[0]? <br />";
?>

<!DOCTYPE html>
<html>
<form action="questions.php" method="post">
<?php
foreach ($answerChoices as $answerChoice) {
echo "<input type='radio' name='ans' id='q1' value=".$ctr."> <label for='q1'>".$answerChoice."</label> <br />";
$ctr +=1;
}
$_SESSION["index"] = $indexTemp +1;
?>
<input type="submit" name="submit" value="GO!">
</form>

</html>

Answer

Before the cookie is set, $_COOKIE['quizTakers'] doesn't exist, and when you call unserialize() on this you set $addUsers to false. Then when you try to do array_push($addUser, $userN);, this fails because $addUser isn't an array, so $addUser is still false. Then you put this into the cookie.

The next time the user runs the script, you read false from the cookie, and the username isn't found in this, so you don't stop the user from taking the quiz again.

You're making this much more complicated than it needs to be. You don't need to put an array into the cookie, because cookies aren't shared by all the users. Just set a cookie to a simple string and test whether the cookie is set.

if (isset($_COOKIE['took_quiz'])) {
    echo "You already took the quiz! <br \>";
    echo "<form action=\"changeUser.php\" method=\"post\"> Go Back: <input type=\"submit\"><br \> </form>";
    exit();
}
setcookie('took_quiz', 'true', time()+86400);

As others pointed out, users can get around this by clearing cookies. So if you need something more secure, you need to implement a login system and use a database or file to track which users have already taken the quiz.