'Why rand() every time I refresh the page?

I want to run mini program for confirmation security question :

$questions = array('dog legs','car legs','the best country in the world');
$answers = array(4,4,'USA');
$questionId = rand(0, (count($questions)-1));

and then

$ans = $_POST['answer'];
if($ans == $answers[$questionId]){echo 'Confirmed !';}

So the prob is that not every time that I answer the answer is correct, because after sending form the rand function runs and changes the question ! Any solutions ?



Solution 1:[1]

You'll need to know what the original question was as well. Easiest way to do that would be just to post the question in the form as a hidden input :

<form>
    <?php echo $questionID; ?>
    <input type="text" name="answer" />
    <input type="hidden" name="question" value="<?php echo $questionID; ?>" />
</form>

and do

$questions  = array('dog legs','car legs','the best country in the world');
$answers    = array(4,4,'USA');
$questionID = rand(0, (count($questions)-1));

if (isset($_POST['answer'])) {
    $answer   = $_POST['answer'];
    $question = $_POST['question'];

    if ( $questions[ $question ] == $answer ) // you're golden
}

Solution 2:[2]

You can pass in the form an hidden input with as value the question ID, that way the id will be resent.

<input type="hidden" name="questionId" value="<?php echo $questionId; ?>"></input>

Then check if the form is submitted.

<?php
if ($_POST['questionID'])
    $questionID = $_POST['questionID'];
else
    $questionID = rand(0, (count($questions)-1));

You can also secure all this by using base64 encoding

Solution 3:[3]

Best way:

Basicly you need to save the question id into the users session.

Workaround:

If thats to complicated, do the following.

Create a secret string. Create md5 from secret string + correct answer. Write the md5 into a form hidden field. On form submission, check if the secret string + given answer returns the md5 from the form.

Unless someone knows your secret string, you are safe even without sessions.

Attention

My workaround has the same problem than storing the question ID into the form like sugegsten in another answer: One could simply manipulate the question ID to always show a once-solved question. Session is the only more or less safe way

Best regards

Zsolt

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Valentin Mercier
Solution 3 Zsolt Szilagyi