網站計數器的設計方法很多,應用不同方法設計的計數器的實效性也不盡相同。在設計計數器中應用到的一些關鍵技術。
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); //將數組轉換成字符串,以","為分隔符
}
?>
