4

我正在使用数据库来存储我的会话数据。我创建了一些函数来查询当前的活动会话并返回一些要在当前页面上使用的值。使用像“SELECT SessionData FROM UserSessions”这样的单个查询并返回查询返回的行数似乎很容易获得打开的会话数。

然后,我想确定哪些站点用户当前“在线”。会话存储正在查看网站的用户的用户 ID。我搜索了又搜索,似乎只找到了用于解码似乎是序列化数据的 session_decode 函数(但反序列化不起作用)。这里唯一的问题是 session_decode 会自动填充 $_SESSION 超全局变量。所以我的问题是,临时存储 $_SESSION 数据,对当前在线的每个用户使用 session_decode,然后将 $_SESSION 变量重置为临时存储的数据是不是“不好”?

function getLoggedInUsers() {
            //NEED SOME ERROR HANDLING AROUND DB STUFF
    $oConn = DB::connect(RF_DSN);

    $oPrep = $oConn->prepare("SELECT SessionData FROM UserSessions WHERE SessionData LIKE ?");

    $oRes = $oConn->execute($oPrep, array("%UserID%"));

    $aCurSession = $_SESSION; //STORE SESSION DATA TO RESET LATER

    $aLoggedInUsers = array();
    while ($oRow = $oRes->fetchRow(DB_FETCHMODE_ASSOC)) {
        if ($oRow == NULL) {
            break;
        }

        $_SESSION = array();

        session_decode($oRow["SessionData"]);

        $aLoggedInUsers[] = new User($_SESSION["UserID"]);

        $_SESSION = array();
    }

    $_SESSION = $aCurSession; //RESET SESSION DATA TO CURRENT ONLINE USER

    return $aLoggedInUsers;
}

在我看来,这会起作用,但是是否有任何已知的情况可能会失败,然后当前用户最终会得到一些其他用户的会话数据,有效地以可能的管理员身份登录或其他什么?在我的 UserSessions 数据库中存储另一个字段来存放 UserID 或类似的东西会更好吗?

**编辑*** 我正在尝试显示所有当前登录用户(已在网站上注册并登录)的用户名。

4

2 回答 2

3

我建议您在会话表中添加一列,该列在会话数据之外单独存储用户 ID。这样您就可以使用 SQL 来获取这样的名称。(使用假设的用户表)

SELECT UserTable.userName FROM SessionData
INNER JOIN UserTable
ON SessionData.userId = UserTable.id

假设您正在使用另一个查询在预定时间段后清除旧会话,此查询将返回每个登录用户的当前会话数据以及包含其用户名的用户表中的用户行。

$_SESSION数组应仅用于存储与用户当前会话相关的信息,而不是站点周围的其他会话。

于 2012-08-24T18:46:15.743 回答
0

我不会对好坏进行价值判断,但肯定会有更简单的方法来做到这一点。最简单的方法是只拥有一个数据库表,您在每次访问页面时使用用户 ID 和时间戳进行更新,并COUNT(*)在最后 15 分钟左右执行一次。使用适当的索引,性能影响可以忽略不计

阅读您发布的一些评论以澄清您在做什么,您可以轻松地针对您的会话表执行此操作。由于“在线用户”并不是很重要,因此用户登录两次并拥有多个会话的可能性并不是那么重要。

于 2012-08-24T19:32:23.237 回答