計數器是網站常見功能,用於統計頁面瀏覽次數。本文提供一個以文字檔儲存計數的基礎範例,並針對原始碼的安全性問題提出改良建議。
<?php
$counterFile = "balong.txt"; // 計數儲存檔案
function displayCounter($counterFile) {
$fp = fopen($counterFile, "rw");
$num = fgets($fp, 5);
$num += 1;
print "您是第 " . $num . " 個看巴泷計數器的家伙";
// 危險:直接執行系統指令刪除與寫入檔案
exec("rm -rf $counterFile");
exec("echo $num > $counterFile");
}
if (!file_exists($counterFile)) {
exec("echo 0 > $counterFile");
}
displayCounter($counterFile);
?>
exec() 直接使用變數未經過濾,若檔案路徑可被控制,攻擊者可執行任意指令rm -rf 極度危險<?php
$counterFile = __DIR__ . "/data/counter.txt";
// 確保資料目錄存在且不可直接網路存取
if (!is_dir(dirname($counterFile))) {
mkdir(dirname($counterFile), 0750, true);
}
// 使用檔案鎖定確保原子性
$fp = fopen($counterFile, "c+"); // 開啟讀寫,不存在則建立
if ($fp && flock($fp, LOCK_EX)) { // 獨佔鎖定
$num = (int)fgets($fp, 20);
$num++;
ftruncate($fp, 0); // 清空檔案
rewind($fp);
fwrite($fp, (string)$num);
fflush($fp);
flock($fp, LOCK_UN); // 釋放鎖定
fclose($fp);
echo "您是第 {$num} 位訪客";
} else {
echo "計數器暫時無法使用";
}
?>
| 方案 | 優點 | 適用場景 |
|---|---|---|
| 資料庫計數器 | 支援高併發、可關聯分析維度 | 中大型網站 |
| Redis/Memcached | 極高效能、支援原子遞增 | 高流量系統 |
| Google Analytics | 免維運、豐富報表 | 不需自建統計 |
| 靜態頁面+JS 非同步統計 | 不影響頁面載入速度 | 靜態網站 |
exec()、system() 等系統指令函數flock())簡單的計數器看似容易,但涉及並發控制、資料一致性與安全性等核心議題,是檢驗後端工程師基本功的好題目。