增强版的计数器
dx_andy
![]()
|
1#
dx_andy 发表于2007-08-22
增强版的计数器
//文章来源:PHP 4.X 与电子商务网站开发实战
//整理:dx_andy //时间:2007.8.17 早 //测试环境:win32 apache2.2.4 php5.2.1 mysql5.0.27 //联系:QQ:45665758 E-mail:[email protected] 现在流行于互联网上的计数器程序(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位访问者!"; ?> 对由上面的程序稍加改动,就可以实现每日的访问量计数和总访问量计数,当然,数据库也需要用相应的扩充和修改,这一点请读者自已完成。 [ 本帖最后由 dx_andy 于 2007-8-22 14:18 编辑 ] |