+ -
当前位置:首页 → 问答吧 → 增强版的计数器,非常实用

增强版的计数器,非常实用

时间:2007-08-26

来源:互联网

//文章来源: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位访问者!";
?>
对由上面的程序稍加改动,就可以实现每日的访问量计数和总访问量计数,当然,数据库也需要用相应的扩充和修改,这一点请读者自已完成。

                         By:dx_andy

作者: dx_andy   发布时间: 2007-08-26

恩,思路还不错!

作者: forest   发布时间: 2007-08-26