最簡版本
<?php
$file = 'count.dat';
$f = fopen($file, 'r');
$count = fread($f, filesize($file));
fclose($f);
echo '訪問人數:' . $count;
$count++;
$f = fopen($file, 'w');
fwrite($f, $count);
fclose($f);
?>
問題與改進
| 問題 | 解決方案 |
| 併發競態條件(計數丟失) | flock($f, LOCK_EX) 獨佔鎖讀寫全程 |
| 首次文件不存在 | if (!file_exists($file)) file_put_contents($file, '0'); |
| 頻繁 I/O 影響性能 | 改用 Redis/Memcached 內存計數,定期落盤 |
| 刷新重複計數 | Session/ Cookie 標記單用戶單會話僅計一次 |
生產級實現(含鎖與 Session 去重)
<?php
session_start();
$file = 'count.dat';
if (!isset($_SESSION['counted'])) {
if (!file_exists($file)) file_put_contents($file, '0');
$f = fopen($file, 'r+');
if (flock($f, LOCK_EX)) {
$count = (int)fread($f, filesize($file));
$count++;
ftruncate($f, 0);
rewind($f);
fwrite($f, (string)$count);
flock($f, LOCK_UN);
}
fclose($f);
$_SESSION['counted'] = true;
} else {
$count = (int)file_get_contents($file);
}
echo '總訪問量:' . number_format($count);
?>
現代替代方案
- Google Analytics / Matomo:專業統計、多維分析、免費額度大
- Redis INCR:
$redis->incr('page_views:' . $pageId) 原子操作、極高性能
- 數據庫計數表:
UPDATE stats SET views = views + 1 WHERE page = ? 便於關聯查詢
- 上一篇文章: PHP 文件上傳極簡示例與安全要點
- 下一篇文章: PHP 圖片型 Submit 按鈕獲取點擊座標
Copyright ©
程式碼之家 All Rights Reserved