提到複雜版,那就用點資料庫好了
在 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會省很多事。
 
   以上~~