简体   繁体   English

难道使用$ _SESSION超全局来获取当前的在线用户,并在以后将其重新设置为当前的会话数据吗?

[英]Is it BAD to use the $_SESSION superglobal to get the current online users, and set it back to the current session data later?

I am using a database to store my session data. 我正在使用数据库来存储会话数据。 I've created some functions to query through the current active sessions and return some values to be used on the current page. 我创建了一些函数来通过当前活动会话进行查询,并返回一些要在当前页面上使用的值。 Getting the number of open sessions seems easy enough with a single query like "SELECT SessionData FROM UserSessions" and return the number of rows returned by the query. 使用单个查询(如“SELECT SessionData FROM UserSessions”)获取打开会话的数量似乎很容易,并返回查询返回的行数。

I then wanted to determine which site users are currently "online". 然后,我想确定哪些网站用户目前处于“在线”状态。 The session stores the UserID of the user who is viewing the website. 会话存储正在查看网站的用户的UserID。 I searched and searched and seemed to only find the session_decode function for decoding what seems to be serialized data (but unserialize doesn't work). 我搜索和搜索,似乎只找到session_decode函数来解码似乎是序列化数据(但反序列化不起作用)。 The only problem here is, session_decode automatically populates the $_SESSION superglobal. 这里唯一的问题是,session_decode会自动填充$ _SESSION超全局。 So my question is, is it "BAD" to temporarily store the $_SESSION data, use session_decode on each user that is currently online, then reset the $_SESSION variable to the temporarily stored data? 所以我的问题是,暂时存储$ _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;
}

It seems to me that this would work, but are there any known cases where this could fail and then the current user would end up with some other user's session data, effectively being signed in as a possible admin or something? 在我看来这可行,但有没有任何已知的情况,这可能会失败,然后当前用户最终会得到一些其他用户的会话数据,有效地作为可能的管理员或其他东西登录? Would it be better to store another field in my UserSessions database that would house the UserID or something like that? 将另一个字段存储在我的UserSessions数据库中以容纳UserID或类似的东西会更好吗?

**EDIT*** I am trying to display the usernames of all the current logged in users (whom have registered on the site, and logged in). **编辑***我试图显示所有当前登录用户的用户名(已在网站上注册并登录)。

What I would recommend is that you add a column to your session table which stores the user id separately outside of the session data. 我建议您在会话表中添加一列,该列在会话数据之外单独存储用户ID。 That way you can use SQL to get the names like this. 这样你就可以使用SQL来获取这样的名字。 (Using a hypothetical user table) (使用假设的用户表)

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

Assuming you're using another query to clean out old sessions after a pre-determined period of time this query will return both the the current session data for each logged in user as well as the user's row from the user table containing their username. 假设您在预定的一段时间后使用另一个查询来清除旧会话,此查询将返回每个登录用户的当前会话数据以及包含其用户名的用户表中的用户行。

The $_SESSION array should only be used for storing information relevant to the user's current session, not other sessions around the site. $_SESSION数组应仅用于存储与用户当前会话相关的信息,而不是用于存储站点周围的其他会话。

I won't go into value judgments of good and bad but there's definitely going to be simpler ways to do it. 我不会进行好的和坏的价值判断,但肯定会有更简单的方法来做到这一点。 The simplest would be to just have a DB table that you upsert on every page access with a user ID and a timestamp and do a COUNT(*) against the last 15 minutes or so. 最简单的是只有一个数据库表,您可以在每个页面访问时使用用户ID和时间戳进行插入,并在最后15分钟左右执行COUNT(*) With proper indexing, the performance impact would be negligible 通过适当的索引,性能影响可以忽略不计

Reading some of the comments you posted clarifying what you're doing, you could just as easily do this against your session table. 阅读您发布的一些评论,澄清您正在做的事情,您可以轻松地对会话表执行此操作。 Since "users online" is not really critical, the possibility of a user being logged in twice and having multiple sessions isn't really all that important. 由于“在线用户”并不是真正重要的,因此用户登录两次并拥有多个会话的可能性并不是那么重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM