//文章来源:PHP 4.X 与电子商务网站开发实战
//整理:dx_andy
//时间:2007.8.17 早
//测试环境:win32 apache2.2.4 php5.2.1 mysql5.0.27
//联系:QQ:45665758 E-mail:dx_andy@163.com
现在流行于互联网上的计数器程序(PHP)一般都很简单,相对来说功能上也相对较少。比如说它只能提供单个的页面使用,对于某些较大的网站来说,还要统计每个专栏的访问量,而不仅仅是首页的访问量。其次,该计数器作弊也很简单,只要不停的刷新,访问量就会不停地向上涨。对一个网站来说,这样是很过分的。
那么,我们应该怎样来改进它呢?
第一方面,我们可以在count数据库中加入一项id,作为记录每个专栏的代号,每一个id对应着一个计数值count。在不同的专栏访问时,只要指定不同的id就行了。对于第二项,可以考虑另建一个辅助的数据表,记录登录者的ip、访问的栏目和上次访问时间time。每当一个访问者访问该栏目时,从数据库里选择其ip和id共同对应的上次访问时间,如果数据库里不存在该ip和id,可以认为这是一个新用户,计数可以加1,如果存在,则比较当与当前时间和上次访问时间。两者之差大于1小时,则计数也可以加1。最后删除数据表中时间与当前时间相差大于1小时的项(这一点是为了防止数据表过于庞大)。
具体看一看实现的方法。
怎样获得访问者的ip?这需要用到一个函数getenv(),其定义为
string getenv(string varname)
其作用是返回环境变量的值,varname是环境变量名。REMOTE_ADDR表示访问者的IP地址。所以用$ipaddress=getenv("REMOTE_ADDR")就可以得到访问者的IP地址。
对时间,可使用time() 函数,以取得系统的UNIX 时间,以秒做单位。一小时的差别可以用3600秒来代替。
让我们来看一看实际的操作过程,假定有三个栏目(即建立3个id)。
建立数据库:
create table encount
(
count int not null,
id int not null
);
insert into encount values(0,0),(0,1),(0,2); //在encount表中插入三个数据
create table ipandtime
(
ip varchar(15),
id int not null,
etime int not null
);
<?php
//增强版的网页计数器
//文件名:enhancecount.php
//代码来源:PHP 4.X 与电子商务网站开发实战
//整理:dx_andy
//时间:2007.8.17 早
//此代码在win32 Apache2.24 PHP5.5.1 MySQL5.0.27环境下测试通过
function enhancecount($id)
{
$ipaddress=getenv("REMOTE_ADDR");
//echo "/$ipaddress=".$ipaddress."<br>/n";
$currenttime=time();
//echo "/$currenttime=".$currenttime."<br>/n";
$link=mysql_connect("localhost","root","123") or die("Unable to conn MySQL!");
mysql_select_db("test") or die("Unable to select DB!");
$query="select etime from ipandtime where ip='$ipaddress' and id='$id'";
$result=mysql_query($query);
//if($result) echo "select etime OK!<br>/n";
if($row=mysql_fetch_row($result))
//如果返回值存在,则执行下面语句。
{
$timestamp=$row[0];
//echo "/$timestamp=".$timestamp."<br>/n";
//echo "/$currenttime-/$timestamp=".($currenttime-$timestamp)."<br>/n";
if($currenttime-$timestamp>3600)
//如果时间超过1个小时,则更新。
{
$query="update ipandtime set etime='$currenttime' where ip='$ipaddress'";
mysql_query($query);
$query="delete from ipandtime where etime<('$currenttime'-3600)";
mysql_query($query);
$update=1;
$count=updatecount($id,$update);
mysql_close($link);
return($count);
exit();
}
//如果小于1小时,只执行删除大于一小时的表项的命令。
$query="delete from ipandtime where etime<('$currenttime'-3600)";
$dele=mysql_query($query);
//if($dele) echo "Small Delete ipandtime is OK!<br>/n";
$update=0;
$count=updatecount($id,$update);
mysql_close($link);
return($count);
exit();
}
//如果不存在,更新数据,并将该ip插入数据库。
$query="insert into ipandtime(ip,id,etime) values('$ipaddress','$id','$currenttime')";
mysql_query($query);
$query="delete from ipandtime where etime<('$currenttime'-3600)";
mysql_query($query);
$update=1;
$count=updatecount($id,$update);
return($count);
}
//更新数据库encount的函数,形参为id和布尔量update
function updatecount($id,$update)
{
// echo "function updatecount /$id=".$id." /$update=".$update."<br>/n";
$query="select count from encount where id='$id'";
$result=mysql_query($query);
$answer=mysql_fetch_row($result);
$count=$answer[0];
if($update)
{
$count++;
$query="update encount set count='$count' where id='$id'";
mysql_query($query);
}
return($count);
}
?>
上面的函数enhancecount()的返回值为$count,只要在其他需要使用的文件里调用就行了。
比如,假设某一需要调用该文件的栏目的id为2,那么只要用如下语句就可以达到调用它的目的。
<?php
require('enhancecount.php');
$count=enhancecount(2);
echo "您好,您是第$count位访问者!";
?>
对由上面的程序稍加改动,就可以实现每日的访问量计数和总访问量计数,当然,数据库也需要用相应的扩充和修改,这一点请读者自已完成。