网站计数器的设计方法很多,应用不同方法设计的计数器的实效性也不尽相同。在设计计数器中应用到的一些关键技术。
1.通过Session防止重复计数
此方法可以应用到任意一个计数器中实现控制重复计数的功能。其实现的原理是:在当前页被访问时,初始化一个Session变量,并赋给其一个空值。
然后,判断Session变量的值是否为空,如果为空,则将计数器的值增加1,并且为Session变量赋值为1。
此时,在当前页中,Session变量的值已经不为空,无论如何刷新,Session变量的值都不会改变,所以计数器的值也不会增加。关键代码如下:
<?php
if(!isset($_SESSION)){ session_start(); } //初始化SESSION变量 $f_open = fopen("./count.txt","r+"); //打开指定的文件 $count = fgets($f_open); //读取文件中的数据 if($_SESSION[temp]==""){ //判断$_SESSION[temp]==""的值是否为空 $count = $count + 1; //将变量$count的值加1 rewind($f_open); //打开指定的文件 fwrite($f_open,$count); //向文件中写入新的数据 fclose($f_open); //关闭文本文件 $_SESSION[temp]=1; //$_SESSION[temp]的值不为空,给$_SESSION[temp]赋一个值1 } ?
Session变量防止重复计数的缺点是只对当前页面有效,当重新打开该页面时,计数器的值仍然会增加。
(1)fopen()函数,打开某文件,并返回该文件的标识指针。语法如下:
resource fopen(string filename, string mode [, int use_include_path [, resource context]])
// 在fopen()函数的mode参数中,其指定的打开模式很多,其中常用的有如下几种。
// ‘r‘只读方式打开,将文件指针指向文件头。
// ‘r+‘读写方式打开,将文件指针指向文件头。
// ‘w‘写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建。
// ‘w+‘读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建
(2)fgets()函数,获取文件指针所在行指定长度的内容。语法:
string fgets(int handle [,int length]) //handle:必要参数。指应用fopen()或fsockopen()函数成功打开文件或连接上服务器后所返回的文件标识。 //length:可选参数。用于指定读取一行最多的字节数,并返回length−1个字节的字符串。如果省略该参数,则length的长度默认为1 024个字节。
(3)fputs()函数,fwrite()函数的别名。将字符串写入指定的文件中,并可以规定写入字节的大小。语法:
int fwrite( resource handle, string string [, int length])
2.通过Cookie防止重复计数
通过Cookie防止重复计数的实现原理与Session的原理相同,惟一的区别是Session是对当前页进行操作,而Cookie则是从时间上防止重复计数。
通过Cookie防止重复计数,同样在当前页被访问时,判断指定的Cookie变量是否存在,如果不存在,则将计数器的值增加1,并且创建一个Cookie变量,设置Cookie的过期时间;如果Cookie变量存在,则不执行计数器加1的操作。关键代码如下:
<?php $f_open = fopen("count.txt","r+"); //打开指定的文件 $count = fgets($f_open); //读取文件中的数据 if(empty($_COOKIE[‘cookie_name‘])){ //判断Cookie是否存在 setcookie("cookie_name",value,time()+1800); //如果不存在,则创建Cookie
$count = $count + 1; //将变量$count的值加1
rewind($f_open); //打开指定的文件
fwrite($f_open,$count); //向文件中写入新的数据
fclose($f_open); //关闭文件
}
?>
setcookie()函数,在客户端设置一个Cookie的值,如果成功返回True,否则返回False。setcookie()函数的语法如下:
bool setcookie ( string name [, string value [, int expire [, string path [, string domain [, bool secure [, bool httponly]]]]]] )
参数说明如表1所示。
参 数 |
说 明 |
name |
必要参数。输入的Cookie名字 |
value |
可选参数。输入的Cookie的值,保存在客户端 |
expire |
可选参数。Cookie的有效时间,是个UNIX时间戳,如果未设定,Cookie将会在会话结束后(一般是浏览器关闭)失效 |
path |
可选参数。在服务器的有效路径,默认值为设定Cookie的当前目录 |
domain |
可选参数。有效的域名,例如设置为‘.mingrisoft.com‘,Cookie能在此域名下的所有子域都有效 |
secure |
可选参数。指明是否仅通过安全的https连接中传送 |
httponly |
可选参数。设置此参数为True,则Cookie不会受脚本语言(如Javascript)所影响,此参数是php 5.8.0新加入的 |
通过Cookie防止重复计数的方法,从时间的角度去防止重复计数,只有当Cookie过期之后,计数器的值才会重新增加;否则,计数器的值将一直不会增加。除非人为对计算机的Cookie进行清理之后,计数器的值才会增加。
3.通过IP防止重复计数
通过IP防止重复计数是最准确的方法,它完全通过客户端计算机的IP来防止重复计数,不会有任何时间和页面的限制,只要是已经访问过的IP,计数器的值就不会增加。
通过IP防止重复计数必须要有数据库的支持,服务器会将每个访问过本网站的客户端的IP存储到数据库中。
当客户端的计算机访问本网站时,服务器将会首先获取该客户端的IP地址,并且与数据库中存储的IP地址进行比较,如果数据库中已经存在该IP,则计数器的值将不会增加;否则将计数器的值加1,并且将该IP地址存储到数据库中。关键代码如下:
<?php
if(!isset($_SESSION)){ session_start(); }
include("conn/conn.php"); $data1=date("Y-m-d h:m:s"); //获取当前访问时间 $data2=date("Y-m-d"); //获取当前访问时间 $ip=getenv(‘REMOTE_ADDR‘);//使用数据库存储数据
$query=mysql_query("select * from tb_count04 where ip=‘$ip‘");
$result=mysql_num_rows($query);
if($result>0){
echo "该IP地址已经存在";
}else{
$query="insert into tb_count04(counts,data1,data2,ip)values(‘1‘,‘$data1‘,‘$data2‘,‘$ip‘)";
$result=mysql_query($query);
}?>
通过IP不但可以防止重复计数,而且可以统计出网站被同一IP访问的次数。
4.通过array_unique()函数获取网站当月IP访问量
通过array_unique()函数去除数组中重复的值,从而实现统计网站当月IP的访问量。其中主要应用了array_unique()和count()函数。
(1)array_unique()函数,将值作为字符串排序,然后对每个值只保留第一个键名,忽略所有后面的键名。语法:
array array_unique ( array array)
(2)count()函数,返回数组中的单元数目,用来计算数组中值的个数。语法:
int count ( mixed array [, int mode])
参数array为指定的数组;参数mode为可选参数,COUNT_RECURSIVE(或1),如果选中此参数,本函数将递归地对数组计数。对计算多维数组的所有单元尤其有用。此参数的默认值是0。
在获取网站当月IP的访问量之前,先来看一下存储网站访问量数据的数据表结构,如图1所示。
图1 网站访问量统计数据表
在该数据表中,包括5个字段,分别是ID;网站访问量counts;访问时间data1,完整的时间年月日;访问时间data2,只包括年和月;网站的ip地址。
要获取网站当月IP访问量,其查询条件必须从时间data2着手,查询出当前时间符合data2的数据,代码如下:
<?php $query_4="select * from tb_count10 where data2=‘".substr(date("Y-m-d"),0,7)."‘"; $result_4=mysql_query($query_4);
技巧:
应用substr()函数,获取当前日期中年和月的值,将获取的值与数据表中data2字段的值进行比较,从中读取出符合条件的数据。
然后,将获取到的IP地址写入到一个数组中。代码如下:
while($myrow_4=mysql_fetch_array($result_4)){ $counts_4[]=$myrow_4[ip]; //将获取的ip地址赋给变量 }
最后,应用array_unique()函数去除数组中重复的值,再统计出数组中元素的数量即总的ip访问量。代码如下:
$results_4=array_unique($counts_4); //去除数组中重复的值 $countes_4=count($results_4); //获取数组中值的数量,即总的ip访问量 ?>
5.将数组中的数据写入字符串中
将数组中的数据写入字符串中,主要应用的是current()和implode()函数。
(1)current()函数,返回数组中的当前单元。每个数组中都有一个内部的指针,初始指向插入到数组中的第一个单元。该函数返回当前被内部指针指向的数组单元的值,并不移动指针。如果内部指针指向超出了数组的最大单元,将返回False。语法:
mixed current ( array array)
(2)implode()函数,将数组的内容组合成一个字符串。语法:
string implode(string glue, array pieces)
参数glue是字符之间的分隔符号。
这里实际是将指定月份每天的数据写入字符串中,实现对网站指定月份的访问量进行分析。要完成该操作,首先要以指定的月份为查询条件,查询出指定月份的网站访问量的数据。
<?php $query="select counts from tb_count10 where data2=‘$select‘ order by data1 "; $result=mysql_query($query);
然后,通过while语句,循环读取其中的数据,并且应用current()函数,将数组中当前的元素写入数组$results中。
最后应用implode()函数,将数组$results中的数据写入一个字符串变量$lmbs中,以“,”为分隔符,完成将指定月份每天的数据写入到字符串中的操作。代码如下:
while($myrow=mysql_fetch_array($result)){ //循环读取数据库中数据 $results[]=current($myrow); //将当前元素写入数组中 $lmbs=implode(",",$results); //将数组转换成字符串,以","为分隔符 } ?>