提到複雜版,那就用點資料庫好了
在 3WA 裡面,我設計了二個資料表
counter
跟
counters_user_info
原本 3wa 是想作成無名那樣,也許可以擁有很多個使用者啦,
但隨著功能慢慢增加,有些根本一般使用者都用不到啊,我只好
放棄這樣子的規劃。必竟這網站的類型現階段仍只能自己 High
自己爽啦,除非我把幾個核心的東西再抽出來,專作給使用者來
用,但~即然經營策略又改變了,我看還是作成強大的個人網站
好了。
扯了一堆…
我大概規劃如下
counters 長這樣~
欄位名稱(英) | 欄位名稱(中) | 型態 | 相關參數 |
id |
流水號
|
int(50) unsigned |
Key:PRI Extra:auto_increment |
USER_ID |
哪個使用者
|
varchar(50) |
|
IP |
IP來自何方
|
varchar(15) |
|
date |
日期
|
varchar(8) |
|
time |
時間
|
varchar(6) |
|
老實說,以前我很嫩,不知道可以用 datetime 這東西,才拆成二個很佔空間的欄位…
counters_user_info 資料表大概有下面幾個東西~
欄位名稱(英) | 欄位名稱(中) | 型態 | 相關參數 |
id |
流水號
|
int(5) |
Key:PRI Extra:auto_increment |
USER_ID |
哪個使用者
|
varchar(255) |
|
counters |
已累計的計數
|
int(11) |
Default:0 |
我的設計概念大概如下~
同一個IP,同一天,看哪一個人的網站(當時我考慮我的站是多人使用),各別只會記錄一次~
然後這些資料,最多保留一個禮拜~
因為我想要印出下面這樣子的東西~
累計人數:00025373
今日人數:00000023
昨日人數:00000176
本週人數:00001127
所以,你可以大概知道累計人數是怎樣算出來了,答案就是我需要一個空間,讓他記下最後超過一週後的
人數加總,然後把超出結果的人,從 counters 資料表移除
我們來看一下大概統計了什麼資料~
id | USER_ID | IP | date | time |
29108 |
shadow |
123.125.71.101 |
20100915 |
015510 |
29107 |
shadow |
123.125.71.99 |
20100915 |
014044 |
29106 |
shadow |
124.115.1.8 |
20100915 |
011246 |
29105 |
shadow |
123.125.71.106 |
20100915 |
011157 |
29104 |
shadow |
123.125.71.109 |
20100915 |
005735 |
29103 |
shadow |
61.57.97.26 |
20100915 |
005221 |
29102 |
shadow |
119.147.35.34 |
20100915 |
004722 |
我想表達的就是,同一個ip 同一天只會收集一次啦,原本我是不停的收集,不過覺得沒啥必要了
分析來訪人讓 google 的 分析器去作快多了,網站的任務達成就好
然後藉由查詢的語法,來得到需要的資料
累計人數:00025373
今日人數:00000023
昨日人數:00000176
本週人數:00001127
所謂的累計人數,指的是過去的人數加上 counters 裡面與使用者相同的數量。
$sql="select count(*) from (select * from `counter` where `USER_ID`='".$USER_ID." group by `ip`,`date`)a ";
我之所以把查詢寫成這樣,是因為之前我把每次使用者來都記下來了,任何時間點,任何ip,但後來發現我根本沒在看log,其實就沒啥必要這樣作了,不然計數的東西實在太多,浪費資料庫空間
現在一天只有一筆,其實可以改成這樣
$sql="select count(*) from `counter` where `USER_ID`='".$USER_ID." ";
用 group 去切開的部分都不用了~直接統計就行了
不過這樣統計只會拿到最近的一週資料,還要再加上 info 那個表的最後總值,才是真實累計的人數。
所謂的當日人數,指的是當天的人數 counters ,收看某人網頁的數量。
這很好統計,只要加上時間的判斷~
$sql="select count(*) from (select * from counter where USER_ID='".$USER_ID."' and date=date_format(now(),'%Y%m%d') and kind='main' group by ip,date)a ";
總之就是當天的日期與 資料庫轉型後的「字串」相同。
mysql 可以利用 date_format 來轉 timestamp ,跟 php 一樣好用
那麼,一週的就更簡單嘍
最後的一週人數,指的是一週內的人數 counters ,收看某人網頁的數量。
所以改一下剛才查當日的就行了~
$sql="select count(*) from (select * from counter where USER_ID='".$USER_ID."' and date between date_format(now()-INTERVAL 7 DAY,'%Y%m%d') and date_format(now(),'%Y%m%d') and kind='main' group by ip,date)a ";
-INTERVAL 7 DAY 至於這個怎寫,你只要多念一下 mysql API ,就會知道日期那些怎寫才會快又簡單。
好,繼續來講我們的網頁流程~
我們當然是希望網友來到我們的站台,不管是看哪一頁,都可以達到統計、紀錄的功能啊,總不能一定要回第一頁(首頁)才統計…對吧~
所以,我把這支 counter.php , include 給 conn.php 使用,而 init.php 則是每一次連線都會載入的網頁設定檔,如此一來,只要有載入網頁需要的資料,就可以觸發記數器了。
我們來看一下,如何作累加跟統計的方法~
//超過七天就累加數量,加入 counters的表,並把超過七天的值全刪了
//寫入最後的值
$SQL=sprintf("SELECT DISTINCT `id` FROM `counters_user_info` WHERE `USER_ID`='%s' ORDER BY `id` DESC LIMIT 0,1",$USER_ID);
$res=mysql_query($SQL) or die("找尋使用者的動態數值表失敗:{$SQL}");
$mlast=resulttoobject($res);
if(count($mlast)==0)
{
//建立新使用者的動態數值表
$SQL=sprintf("INSERT INTO `counters_user_info`(`USER_ID`,`counters`)VALUES('%s','0');",$USER_ID);
mysql_query($SQL);
$COUNTERS_ID=mysql_insert_id();
}
else
{
$COUNTERS_ID=$mlast[0]->{'id'};
}
看的霧煞煞嗎…唉~我很不會教人,留神點學吧~
反正大意就是讀出使用者累計的次數,如果讀不出來,就建一筆數值是零的,等著累加。
然後,要寫入counters的資料,要先判斷今天該 IP 有沒有來過,如果有,就不要加了
反則就加入。
由於每一支程式都會檢查,那麼,誰該列印呢?
我在 init.php 或 conn.php 引用了 counter.php 當作每頁的檢查
那麼,我只要選個好地方,用特別的變數來決定是否查詢跟列印可以。
這樣就不會每一頁都印出來了~
if($show_counter=='true')
{
//一堆查詢示,順便列印
}
計數器的開發大致上是如此啦,請原諒我沒有畫出流程圖,因為這實在
滿簡單的,只是需要一點開發的想法跟技巧。
多學習mysql的語法吧,也許我寫的那麼多支,只要一次查詢就好了…
這樣mysql會省很多事。
以上~~