Php 使用$\u SESSION superglobal获取当前在线用户并稍后将其设置回当前会话数据是否不好?

Php 使用$\u SESSION superglobal获取当前在线用户并稍后将其设置回当前会话数据是否不好?,php,mysql,Php,Mysql,我正在使用数据库来存储会话数据。我创建了一些函数来查询当前活动会话,并返回一些在当前页面上使用的值。只需一个查询,就可以轻松获取打开会话的数量,如 “从UserSessions中选择SessionData” 并返回查询返回的行数 然后,我想确定哪些网站用户目前处于“在线”状态。会话存储正在查看网站的用户的用户ID。我搜索了又搜索,似乎只找到session_decode函数来解码似乎是序列化的数据(但unserialize不起作用)。这里唯一的问题是,session\u decode会自动填充$\

我正在使用数据库来存储会话数据。我创建了一些函数来查询当前活动会话,并返回一些在当前页面上使用的值。只需一个查询,就可以轻松获取打开会话的数量,如 “从UserSessions中选择SessionData” 并返回查询返回的行数

然后,我想确定哪些网站用户目前处于“在线”状态。会话存储正在查看网站的用户的用户ID。我搜索了又搜索,似乎只找到session_decode函数来解码似乎是序列化的数据(但unserialize不起作用)。这里唯一的问题是,session\u decode会自动填充$\u session superglobal。因此,我的问题是,临时存储$\u会话数据,对当前联机的每个用户使用会话解码,然后将$\u会话变量重置为临时存储的数据是否“不好”

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或类似的内容会更好吗

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

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

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


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

我不会讨论好与坏的价值判断,但肯定会有更简单的方法。最简单的方法是,只需在每个页面访问中插入一个DB表,其中包含一个用户ID和一个时间戳,并在过去15分钟左右的时间内执行
COUNT(*)
。有了适当的索引,性能影响可以忽略不计


阅读您发布的一些说明您正在做什么的评论,您可以根据会话表轻松地执行此操作。由于“在线用户”并不十分重要,用户登录两次并拥有多个会话的可能性并不那么重要。

为了澄清,您是否为注册到
session\u set\u save\u handler
的数据库编写了自己的会话处理程序?如果是这样的话,您可以添加一列来存储上次访问/修改会话的时间,并仅使用该列通过单个查询确定登录用户。您不能只对SessionData表运行COUNT(*)查询以找出行数(假设每行都是活动会话)并打印该查询的结果吗?像您一样使用_sessionsuperglobal对于查找活动会话的数量似乎有点不必要,除非我遗漏了什么。@drew010是的,我遗漏了。UserSessions表使用3个字段。SessionID,SessionData,LastAccess。LastAccess用于删除活动时间超过一定时间的会话。你建议使用实际用户表而不是会话表吗?@MichaelWheeler我建议你扩展会话表以容纳更多信息。听起来包含用户名的附加列会很有帮助。另外,向该列和LastAccessed列添加索引将使这些查询更加高效。然后,为了简单起见,您可以发出一个查询,如
selectusername FROM UserSessions WHERE UNIX_TIMESTAMP()-LastAccessed@drew010+1,不过只要将LastAccessed字段设置为mysql
TIMESTAMP
就可以免费自动更新,而不必干扰UNIX时间戳转换。谢谢您提供的信息!我需要在write_SESSION()处理程序中使用$_SESSION变量,因为它已经传递了序列化数据。所以只需将会话表的UserID设置为$\u session UserID,对吗?会话表中的
UserID
字段应与用户表中的
id
字段(或其名称)相对应,假设您的应用程序有意义,则每个用户的
$\u session['UserID']
值也应如此。谢谢!这就是我现在正在做的事情。关于用户登录两次,我刚刚添加了一个函数,在登录脚本中删除该用户ID的旧会话。
SELECT UserTable.userName FROM SessionData
INNER JOIN UserTable
ON SessionData.userId = UserTable.id