PHP的在线人数统计[转帖]
现在很多网站或者论坛都有在线人数统计这个功能,管理员看着自己网站的在线人数不断增多,别有一番风味。那么这些在线人数统计是怎么做出来的呢?
要实现在线统计,有两种方法。
第一种是使用一个Socket和请求者连接,直到请求者的Socket断开,就把数据库中的记录删除,然而这种方法过于复杂。
现在的网页都是基于HTTP协议,HTTP协议连接的生命期从请求者发出请求到HTTP回话结束完毕,也就是如果页面读取完毕,连接就关闭了。而第二种方法就是计算在某段时间之内的请求数目。
知道了这个请求的数目,又怎么确定在线人数呢?我们在数据库中记录下此IP上次访问的时间,然后在统计在线人数的时候,如果某IP上次访问时间和当前时间的差值小于某个值的时候,就认为本用户仍然在线。而这个时间差值可以是5分钟,可以是15分钟,甚至可以是1个小时,要视不同网站而定。
记录IP对应的访问时间,这里使用文本数据库,结构如下:
IP地址 │ 请求的URI │ 最后请求的时间戳
为什么要使用文本记录而不使用类似MySQL的SQL数据库呢?记录数据有方法,一是即使请求者已经被判定“不在线”,仍然在数据库中保留请求者的记录,但是这样子数据库的大小会像雪球一样越来越大,最终数据库不堪重负。第二种是当请求者被判定“不在线”的时候就将其所对应的记录删除,然而这样子就要频繁的写数据库,会造成数据库文件的分段,文本文件在这种情况下效率不会低于SQL数据库,甚至超过SQL数据库。
下面就是统计在线人数的程序:
--------程序间后----------- 如果在其他页面需要调用在线人数统计,只要在页面上面加入一句:
<s cript src=在线统计程序的URL></s cript>
就可以了。
以上程序在Windows2000 Professional+Apache1.3.19+PHP 4.05和RedhatLinux7+Apache1.3.12+PHP4.04两个平台中测试通过,当文本文件中有10000条记录时,遍历时间耗时0.4秒。
code:
--------------------------------------------------------------------------------
<?
$datafile = 'online.dat'; // 数据文件,如果是linux/unix系统,需要把文件属性设置为777或者666
$onlineTime = 300; // 在线的时间差秒数,这里设置为5分钟 $timestamp = time(); // 取得当前的Unix时间戳
$dat = file($datafile); // 将数据文件读入数组
$count = count($dat); // 取得当前的数据记录数目
$onlineCount = 1; // 在线人数,起始就是1,当前的请求者自己
$insertMe = true; // 判断是否要插入当前请求者的记录,如果当前数据中没有此IP的记录就加入 for($i = 0; $i < $count; $i++) {
$dat[$i] = chop($dat[$i]); // 去处记录尾部的\n
list($ipadd, $requestUri, $lastRequest) = explode('│', $dat[$i]); // 取得数据
if($ipadd == $REMOTE_ADDR) { // 如果IP和当前请求者的IP一致,就更新Unix时间戳
$dat[$i] = $ipadd.'│'.$requestUri.'│'.$timestamp."\n";
$insertMe = false;
} else {
// 如果IP和当前请求者IP不一致,那么判断是否在线
if($lastRequest < ($timestamp - $onlineTime)) {
// 不在线,删除本条数据记录
$dat[$i] = '';
} else {
// 在线,加上尾部的\n
$dat[$i] .= "\n";
$onlineCount++; // 在线人数加1
}
}
}
// 用Javas cript输出结果
print <<< EOF
document.write("在线人数:$onlineCount");
EOF;
// 将新的数据整合成为字符串
$newDat = join('', $dat);
if($insertMe) {
// 判断是否需要加入当前请求者的记录
$newDat .= $REMOTE_ADDR.'│'.$REQUEST_URI.'│'.$timestamp."\n";
}
// 写入数据文件
$fp = fopen($datafile, 'w');
fwrite($fp, $newDat);
fclose($fp);
?>
来自:y10k
现在很多网站或者论坛都有在线人数统计这个功能,管理员看着自己网站的在线人数不断增多,别有一番风味。那么这些在线人数统计是怎么做出来的呢?
要实现在线统计,有两种方法。
第一种是使用一个Socket和请求者连接,直到请求者的Socket断开,就把数据库中的记录删除,然而这种方法过于复杂。
现在的网页都是基于HTTP协议,HTTP协议连接的生命期从请求者发出请求到HTTP回话结束完毕,也就是如果页面读取完毕,连接就关闭了。而第二种方法就是计算在某段时间之内的请求数目。
知道了这个请求的数目,又怎么确定在线人数呢?我们在数据库中记录下此IP上次访问的时间,然后在统计在线人数的时候,如果某IP上次访问时间和当前时间的差值小于某个值的时候,就认为本用户仍然在线。而这个时间差值可以是5分钟,可以是15分钟,甚至可以是1个小时,要视不同网站而定。
记录IP对应的访问时间,这里使用文本数据库,结构如下:
IP地址 │ 请求的URI │ 最后请求的时间戳
为什么要使用文本记录而不使用类似MySQL的SQL数据库呢?记录数据有方法,一是即使请求者已经被判定“不在线”,仍然在数据库中保留请求者的记录,但是这样子数据库的大小会像雪球一样越来越大,最终数据库不堪重负。第二种是当请求者被判定“不在线”的时候就将其所对应的记录删除,然而这样子就要频繁的写数据库,会造成数据库文件的分段,文本文件在这种情况下效率不会低于SQL数据库,甚至超过SQL数据库。
下面就是统计在线人数的程序:
--------程序间后----------- 如果在其他页面需要调用在线人数统计,只要在页面上面加入一句:
<s cript src=在线统计程序的URL></s cript>
就可以了。
以上程序在Windows2000 Professional+Apache1.3.19+PHP 4.05和RedhatLinux7+Apache1.3.12+PHP4.04两个平台中测试通过,当文本文件中有10000条记录时,遍历时间耗时0.4秒。
code:
--------------------------------------------------------------------------------
<?
$datafile = 'online.dat'; // 数据文件,如果是linux/unix系统,需要把文件属性设置为777或者666
$onlineTime = 300; // 在线的时间差秒数,这里设置为5分钟 $timestamp = time(); // 取得当前的Unix时间戳
$dat = file($datafile); // 将数据文件读入数组
$count = count($dat); // 取得当前的数据记录数目
$onlineCount = 1; // 在线人数,起始就是1,当前的请求者自己
$insertMe = true; // 判断是否要插入当前请求者的记录,如果当前数据中没有此IP的记录就加入 for($i = 0; $i < $count; $i++) {
$dat[$i] = chop($dat[$i]); // 去处记录尾部的\n
list($ipadd, $requestUri, $lastRequest) = explode('│', $dat[$i]); // 取得数据
if($ipadd == $REMOTE_ADDR) { // 如果IP和当前请求者的IP一致,就更新Unix时间戳
$dat[$i] = $ipadd.'│'.$requestUri.'│'.$timestamp."\n";
$insertMe = false;
} else {
// 如果IP和当前请求者IP不一致,那么判断是否在线
if($lastRequest < ($timestamp - $onlineTime)) {
// 不在线,删除本条数据记录
$dat[$i] = '';
} else {
// 在线,加上尾部的\n
$dat[$i] .= "\n";
$onlineCount++; // 在线人数加1
}
}
}
// 用Javas cript输出结果
print <<< EOF
document.write("在线人数:$onlineCount");
EOF;
// 将新的数据整合成为字符串
$newDat = join('', $dat);
if($insertMe) {
// 判断是否需要加入当前请求者的记录
$newDat .= $REMOTE_ADDR.'│'.$REQUEST_URI.'│'.$timestamp."\n";
}
// 写入数据文件
$fp = fopen($datafile, 'w');
fwrite($fp, $newDat);
fclose($fp);
?>
来自:y10k
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货