我正在寻找一种简单(无数据库)的方法来列出网站上有多少用户活跃。我能想到的最简单的方法是计算开放会话的数量。
此代码应该有效:
$number_of_users = count(scandir(ini_get("session.save_path")));
当然它不会因为该目录的安全限制(因为应该有!!)。有没有人知道在不更改目录权限的情况下访问此号码的另一种方式。
注意:我正在寻找不涉及数据库或降低PHP会话安全性的选项。
结束注意:对于任何人来到这个问题,我最终使用了一个来自root的cronjob(每分钟运行一次),它做了类似的事情:
ls /var/lib/php5/ | wc -l > /var/www/sessioncount
确保apache用户可以读取/var/www/sessioncount
文件。然后你可以用PHP读取文件:
$number_of_users = file_get_contents("/var/www/sessioncount");
答案 0 :(得分:5)
<?
// you must set your own accessible session path atop every page.
session_save_path("/home/some/other/location/"); # SECURITY VIOLATION!!!
session_start();
function session_count() {
$filter = "sess_";
$files = scandir(session_save_path());
$count = 0;
foreach ($files as $file) {
if(strpos($file,$filter)===0) {
$count += 1;
}
}
return $count;
}
echo session_count();
?>
答案 1 :(得分:4)
在这种情况下,Easy并不意味着没有数据库。还依靠会话来查看有多少用户是不可靠的。
如果你想走这条路,你可以每隔几分钟做一个由安全进程运行的cronjob,并将该数量保存到PHP读取的文件或数据库中。
但我建议你去数据库路线。
答案 2 :(得分:2)
为了解决这个问题,请点击此处。按顺序组装代码,并在途中使用指示。需要PHP的GD扩展。
在您的webroot中创建一个目录,确保Web守护程序可以写入它:
mkdir liveusers
为 touch 代码创建 PHP脚本(例如 vlive.php )(顺便说一句.touch是标准的* nix命令,使用system(),passthru()或exec()无论你想使用它,都可以使用它。让触摸该目录中的文件具有唯一的文件名,例如IP + SessionID连接在一起:
<?php
exec("touch ". $_SERVER['DOCUMENT_ROOT']."/liveusers/". md5($_SERVER['REMOTE_ADDR'].session_id())); /* SECURITY RISK */
现在,在同一个文件中,我们需要输出一个JPEG,用正确的标题完成它()我把一个名为 pixel.jpg 的1x1像素输入到webroot的 / images / directory ,随意做其他事情:
$NewImage = imagecreatefromjpeg($_SERVER['DOCUMENT_ROOT']. "/images/pixel.jpg");
header("Content-type: image/jpeg");
imagejpeg($NewImage);
?>
保存PHP文件,然后在文档中放置标准HTML标记以使其有用:
<img src="/vlive.php" alt="Imagination!" />
使用纯粹的PHP然后缓存页面只会使实时用户文件几乎不能触摸'd。通过这样做,您仍然可以计算“实时”用户并在您的网站上使用整页缓存系统。
好的,现在访问者加载的每个页面都会触及他们的唯一文件,因此如果他们刚刚到达,则触摸命令将为该用户创建一个文件,如果他们也访问其他页面,它将编辑访问日期那个触摸命令。
这是有用的地方:
在另一个PHP脚本中(假设 readvlive.php ):
<?php
$livenum = system("find ".$_SERVER['DOCUMENT_ROOT']."/liveusers/ -type f -amin +10 | wc -l");
echo "Live Visitors: ". $livenum;
?>
现在让我们将这个片段包含在您希望在其中看到的HTML元素中:
<?php include($_SERVER['DOCUMENT_ROOT']. "/readvlive.php"); ?>
好的,现在我们有一个文件,它会打印出仅在10分钟前更改访问时间的唯一文件数。这些是我们过去十分钟的实时用户......
现在我们可以在这里进行选择,如果您使用整页缓存,则可能会将缓存的实时号码冻结到这些文档中,从而使其变得相当恼人和无用。为此,我建议使用PrototypeJS(Google it),使用他们喜欢的AJAX工具,将它放在 <head></head>
<script src="/js/prototype.js" type="text/javascript"></script>
然后将其置于 </body>
标记上方。
<span id="live_users_count"> </span>
<script type="text/javascript">
<!--
Event.observe(window, 'load', function() {
if($('live_users_count')) {
new Ajax.Updater('live_users_count','/readvlive.php');
}
}
-->
</script>
应该没问题......不要太粗糙。如果您担心目录将运行该命令的程度,您可以使用APC或其他东西来缓存它。 此示例需要APC 3.1.4:
<?php
if(apc_exists('livenum')){
$livenum = apc_fetch('livenum');echo $livenum;
} else {
$livenum = system("find ".$_SERVER['DOCUMENT_ROOT']."/liveusers/ -type f -amin +10 | wc -l");
apc_add('livenum',$livenum,30);
}
?>
APC 3.0.13及以上:
<?php
if($livenum = apc_fetch('livenum')){
echo $livenum;
} else {
$livenum = system("find ".$_SERVER['DOCUMENT_ROOT']."/liveusers/ -type f -amin +10 | wc -l");
apc_add('livenum',$livenum,30);
}
?>
这些将使用APC缓存30秒显示最后10分钟的实时用户,将运行find命令每分钟计算两次。不错。 :P
可以使用crontab进行清理..
脚本( /root/deloverhead.sh ):
#!/bin/sh
find "/path/to/liveusers/ -type f -amin +60 -exec rm {} \;
Crontab条目(每小时):
0 * * * * /root/deloverhead.sh >/dev/null 2>&1
玩得开心,抱歉,我可能会解释一些奇怪的事情。 :P
答案 3 :(得分:0)
您不能从PHP脚本访问该目录而不会带来安全风险。
实现您想要的最简单方法是使用数据库。只需存储ip和时间戳,然后根据时间戳选择SELECT以获取您网站上的活跃用户数。