PHP執行個體剖析:計數器
作者:Sucre_tiger
本款計數器用文本計數,沒有用到資料庫,可以實現如下功能:
利用一個文字檔實現多個頁的計數減少伺服器的I/O佔用率在需要紀錄的檔案裡,只需加入很少的幾行代碼
基本思路如下:
伺服器程式從文字檔中讀取該頁被瀏覽的次數,(因為所有檔案向伺服器提出請求時,他們的環境變數REQUEST_URI都代表他來自於何處... ...,所以,以請求檔案的環境變數REQUEST_URI來辨別到底是那一頁正被瀏覽。),將這個次數加一儲存,並在調用這頁的使用者的電腦上顯示出來。
請先看我的資料文本中紀錄的資料樣本,(紅色為瀏覽次數,其前面為相應的被瀏覽的檔案)
Counter.dat/script/s2.php|3|/script/s1.php|11| /script/counter.php|5| /testhtml/s2.php|7|/testhtml/s3.php|6|
Now,Let's go!
counter.php
複製代碼 代碼如下:<html><head>
<title>計數器</title>
<head>
<body>
<?php
/* 定義儲存資料的文字檔 */
$counterFile="counter.dat\";
/* 定義一個標記,用來辨別現在需紀錄的資料是否已經文本資料中 */
$sign=False;
/* 將資料以數組的方式讀入變數 $sounterData 備用, */
$counterData=file($counterFile);
/* 用count()Function Compute共有多少個紀錄 */
/* 用explode()函數把$counterData[$i]按符號\"|\"分開,並以數組的方式送回到變數$varArray裡 */
/* 函數implode()與explode()剛剛相反,把數組$varArray以符號\"|\"串連起來送回到$counterData */
/* 還利用了環境變數$PATH_INFO
for($i=0;$i<=count($counterData)-1;$i++)
{
$varArray=explode(\"|\",$counterData[$i]);
if ($varArray[0]==$GLOBALS[\"REQUEST_URI\"])
{
$varArray[1]++;
print($varArray[1]);
$counterData[$i]=implode(\"|\", $varArray);
$sign=True;
/* 找到本紀錄所在的位置後, 用break 退出迴圈 */
break;
}
}
/* 在這裡,利用implode()這個函數的功能,將資料整理好了,一起寫入文字檔中 */
/* 這樣,對伺服器的I/O佔用就降到了最低點
$data=implode(\"\",$counterData);
/* 開啟文字檔,將資料寫入 */
$fp=fopen($counterFile,\"w\");
fputs($fp,$data);
/* 如果需要紀錄的資料不在文本裡,標誌$sign= Flase, 那麼就往文本裡添加資料 */
if (!$sign) {fputs($fp,\"\\n\".$GLOBALS[\"REQUEST_URI\"].\"|\".\"1\".\"|\");
print(\"1\");
/* 關閉資料檔案 */
fclose($fp);
?>
</body>
</html>
我們已經看到了這段程式的工作過程,也都知道了思路,但如果,每個檔案裡都這樣寫,豈不是太麻煩.
別慌! 我們還有PHP提供的強大的require()功能呢! 我們把counter.php寫成函數,使用就方便許多了。那還等什麼,下面就是你所要的函數:
counter.inc 複製代碼 代碼如下:<?php
function Counter()
{
$counterFile=\"/freespace/sucre/public_html/counter.dat\";
$counterData=file($counterFile);
$sign=False;
for($i=0;$i<=count($counterData)-1;$i++)
{
$varArray=explode(\"|\",$counterData[$i]);
if ($varArray[0]==$GLOBALS[\"REQUEST_URI\"])
{
$varArray[1]++;
print($varArray[1]);
$counterData[$i]=implode(\"|\", $varArray);
$sign=True; break;
}
}
$data=implode(\"\",$counterData);
$fp=fopen($counterFile,\"w\");
fputs($fp,$data);
if (!$sign)
{
fputs($fp,\"\\n\".$GLOBALS[\"REQUEST_URI\"].\"|\".\"1\".\"|\");
print(\"1\");
}
fclose($fp);
}
?>
最好的檢驗方法就是“實踐”,好了來看我們怎樣調用它,先看一個例子:
counterTest.php
<?php
require(\"counter.inc\");
?>
<html>
<head>
<title> 網頁計數器 終結版 </title>
</head>
<body>
您是第<? counter();?>位閱讀者
</body>
</html>
您只需在要計數的HTML檔案的檔案頭加入require()函數,引入counter()函數為homepage的一部分。在需要的地方加入<? counter();?>就可以了。
還有幾點要注意的問題:
1、 記錄資料的檔案一定要有“寫”的許可權,一般設成“666”即可,如果該檔案存放在一個子目錄下,則對這個“目錄”也要有“寫”的許可權;
2、 我在調試過程中遇到這樣一個問題,我將counter.inc和counter.dat放在一個子目錄include下面,然後在不同的子目錄下面用require()函數進行調用,格式如下:<?php
require("../include/counter.inc")
?>
可是總是出現“許可權不夠”的錯誤,如有高手請指教。