在 PHP 中循环遍历所有服务器的会话

Posted

技术标签:

【中文标题】在 PHP 中循环遍历所有服务器的会话【英文标题】:Looping Through All a Server's Sessions in PHP 【发布时间】:2010-10-15 02:59:24 【问题描述】:

php 中有没有办法获取服务器上所有会话(以及每个会话中的变量)的列表?

基本上,我们有一个维护功能,需要知道哪些用户当前登录到该站点。我们已经将每个用户的数据存储在一个会话变量中,但我希望我可以遍历每个会话并提取出我需要的数据。

我的 PHP 非常有限(我通常是 .Net 开发人员),但如果有人知道这是否可能(以及如何做),我将不胜感激。我用谷歌搜索了这个,我发现的结果往往表明这是不可能的,但我觉得这很难接受。

不过,如果你不能,但我认为我在 *** 上的朋友可以给我一个明确的答案!

【问题讨论】:

【参考方案1】:

PHP 将每个用户的会话数据存储在服务器上的一个临时文件夹中。该文件夹在 php.ini 配置文件中的变量 session.save_path 下定义。从您的 php.ini 文件中找到此值,或者创建一个 php 文件:

<?php echo "Session Save Path: " . ini_get( 'session.save_path');?>

按照它的内容,然后在浏览器中打开文件。

找到会话数据的保存路径后,打开该文件夹,您会发现一个相当简单的结构。所有会话都以以下格式存储: sess_$SESSIONID 。

会话数据在存储到磁盘之前被序列化。因此,存储在会话文件中的对象必须在可用之前进行反序列化。但是,如果您使用按原样存储的纯文本来存储会话数据(例如$_SESSION['userid'] = 1234)来存储有关用户的信息,那么解析出您正在查找的数据应该很容易从文件中获取。

还有一件事……我还没有研究过,但文件名中显示的会话 ID 似乎直接对应于,例如,存储在用户计算机上的 PHPSESSID cookie 的名称。因此,考虑到这一点,可以遍历临时会话目录中的文件,获取所有 $SESSIONID 值,使用 session_id($SESSIONID) 设置当前会话 ID,使用 session_start() 启动会话并访问数据您需要通过 PHP 而不必自己解析内容文件。谁能确认这是否可行?

编辑:调整帖子以匹配 Itay 的评论。

【讨论】:

值得一提的是,这种 hack 是很糟糕的主意。 PHP 具有“无共享”架构,尝试破解它就像使用螺丝刀种植钉子一样。与其解析服务器内部文件,不如创建自己的文件,或者更好地使用数据库来保存您需要的任何内容。 php 可以选择将会话数据保存在内存中。我们并不总是可以将它们从文件中取出。 等等,那些“ses_*”文件可能被放置在多级目录结构下。这就是 php.net 中所说的 你还能检测出哪些是活跃的atm吗?【参考方案2】:

这是通过存储文件获取会话列表的更简洁的方法:

<?php
print_r(scandir(session_save_path()));
?>

【讨论】:

【参考方案3】:

这将为您获取所有会话的数据,存储在数组中并按会话 ID 进行索引:

<?php
$allSessions = [];
$sessionNames = scandir(session_save_path());

foreach($sessionNames as $sessionName) 
    $sessionName = str_replace("sess_","",$sessionName);
    if(strpos($sessionName,".") === false)  //This skips temp files that aren't sessions
        session_id($sessionName);
        session_start();
        $allSessions[$sessionName] = $_SESSION;
        session_abort();
    

print_r($allSessions);

【讨论】:

最后 - 找到这个答案花了太长时间。谢谢! 虽然这会显示所有会话,但它也会将您设置为登录到最后一个可见会话。有没有办法恢复用户当前会话(特别是“未登录”会话)? @user1274820 你只需要在 $originalSession = session_id(); 之前和 session_id($originalSession); session_start(); 之后。这将恢复原始会话。【参考方案4】:

我在ajax调用中使用了@mgroat方法,但是HTTP响应的头部出现了Set-Cookie头部多次出现jQuery报错的问题:

Set-Cookie 标头在来自 url 的响应中被忽略: mysite.com/admin/ajax/main_ajax。 Cookie 长度应该更短 大于或等于 4096 个字符。

解决方案是在session_start() 之后添加header_remove("Set-Cookie")

【讨论】:

以上是关于在 PHP 中循环遍历所有服务器的会话的主要内容,如果未能解决你的问题,请参考以下文章

Java通过遍历sessionId获取服务器所有会话session

PHP脚本循环遍历目录中的所有文件?

Django-Jquery 循环遍历所有选项

php 循环遍历文件夹下面的所有目录及文件并且每个文件都写入一句话

在 PHP 中增加会话变量的问题。它只增加一次

PHP 会话的最大大小