1

我对 PHP 很陌生,所以我正在做一个简单的项目来练习。但是,我无法使会话管理正常工作。

我想要的是,当浏览器关闭时,数据(用户所在的当前页面)会保存一个小时。如果用户在一小时内返回,他应该看到他离开的同一页面,如果他在一小时后返回,他应该看到第一个问题。

当所有问题都被回答后,他应该看到一个分数屏幕,带有一个“再试一次”按钮,该按钮最好销毁/终止/删除会话并开始一个新会话,将用户引导到第一个问题。

如果我遗漏了第 3-8 行,我的代码会按预期工作,我会遍历所有问题,直到我卡在分数屏幕上并使用不起作用的“再试一次”按钮,我只能通过关闭返回第一个问题并重新打开浏览器。

使用这些行,页面可以很好地解决问题,但是当我重新启动浏览器时,它会从第一个问题开始。当我不做任何事情关闭浏览器并再次打开页面时,我找到了我最初离开的页面。我关闭并再次打开浏览器,我再次找到正确的页面,我再次这样做,我回到问题 0。无论我多久重新启动浏览器,我都停留在问​​题 0。

当我在浏览器中查看 cookie 时,我一直都有相同的 cookie,它从 2015 年 12 月 14 日 18:48:45 开始。但是,执行时间也不正确,因为那是 2061 年 11 月 26 日 13:37:29,而不是一个小时后。我究竟做错了什么?

这是我的代码:

<?php
/* Sart (new) session*/
if (isset($_GET['TryAgain'])){
    session_start();
    $_SESSION = array();
    session_destroy();
}
session_set_cookie_params(time()+3600);
session_start();
/*-------------------------------------------------------------------*/

/* IMPORT DATABASE: $qs[i]=question text, $as[i]=array(choices per question),
$as[i][i]=array('t'=>choice text, 'c'=>BOOLEAN) */
require_once('config.php');
$dbh = new PDO("mysql:dbname=$db;host=$host", $user, $password);
$questions = $dbh->prepare('select * from questions');
$questions->execute();
$choices = $dbh->prepare('select * from choices');
$choices->execute();
$qs = array();
$as = array();

foreach($questions as $row) {
    $i = $row['q_nr'];
    $qs[$i] = $row['q_text'];
}

foreach($choices as $row) {
    $qi = $row['q_nr'];
    $ci = $row['c_nr'];
    $as[$qi][$ci] = array('t'=>$row['c_text'],'c'=>$row['correct']);
}
/*-------------------------------------------------------------------*/
/*INITIALIZE SESSION VARIABLES*/

/* Creates counter-variable if not set -------- (ini value is 0)*/
if(!isset($_SESSION['counter'])) {
    $_SESSION['counter'] = 0;
}

/* Creates score-variable if not set -------- (ini value is 0)*/
if(!isset($_SESSION['score'])) {
    $_SESSION['score'] = 0;
}
/*-------------------------------------------------------------------*/
/* SET COUNTER, SCORE AND DONE*/

/* Check if answer previous question has been submitted*/
if (isset($_GET['a'])) {
    $submitted = true;
} else {
    $submitted = false;
}

/* Set counter*/
if ($submitted){
    $_SESSION['counter'] += 1;
}
$cqi = $_SESSION['counter'];

/* Set score*/
if ($submitted) {
    if ($as[$cqi-1][$_GET['a']]['c']){
        $_SESSION['score'] += 1;
    }
} 
$score = $_SESSION['score'];

/* Check done*/
if($cqi >= count($qs)){
    $done = true;
} else {
    $done = false;
}

echo 'cqi: '.$cqi;
echo 'done: '.$done;
/*-------------------------------------------------------------------*/
?>

<!-- START HTML!!! -->

<html>
    <head>

    </head>
    <body>
    <br><br>
    <?php 
        if($done){
            echo 'You finished the quiz. <br> Your score is: '.$score;
            echo "<form action='index.php' method='get'>";
            echo "<input type='hidden' name='TryAgain' value=true>";
            echo "<input type='submit' value='Try again!'>";
            echo "</form>";
        } else {
            echo $qs[$cqi];
            echo "<form action='index.php' method='get'>";
            $cci = 0;
            foreach($as[$cqi] as $cc){
                echo "<input type='radio' name='a' value=".$cci.">".
                $cc['t']."<br>";
                $cci++;
                }
            echo "<input type='submit' value='Next question'>";
            echo "</form>";
            echo "<br><br>Current score: ".$score;
        }
    ?>
    </body>
</html>

请帮助我,我真的被这个困住了。

-编辑-

我再次尝试省略第 3-8 行并保留session_set_cookie_params(600);, 以尽可能简单地测试此功能。我以与上述相同的方式对其进行了测试,一次又一次地重新打开浏览器并记下我得到的问题(q. 0 或 1)。我得到了一个看似随机的模式,第一个问题 0 和我应该回答的问题 1,其中 0 通常是最普遍的。我很确定它是随机的,因为我删除了 cookie 并多次重新进行测试,每次我看到不同的模式。不过,cookie现在确实在正确的时间过期。

正如另一个问题中所建议的那样,我也尝试了ini_set('session.cookie_lifetime', 600);代替session_set_cookie_params(600);功能,但我仍然有随机结果。如果我什至无法做到这一点,我认为尝试创建一个登录系统对我来说不是一个好主意......

4

0 回答 0