無需資料庫,利用文件記錄每個訪客 IP 與最後活躍時間戳,定期清理超時記錄 (默認 15 分鐘),即時返回在線人數。適合中小流量站點、靜態頁嵌入。
function countOnline(int $timeout = 900): int {
$file = __DIR__ . '/online_count.txt';
$now = time();
$ip = $_SERVER['HTTP_CLIENT_IP'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? 'unknown';
// 讀取現有記錄
$records = [];
if (file_exists($file)) {
$lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
[$ts, $recordIp] = explode("\t", $line, 2);
if ($now - (int)$ts < $timeout) {
$records[$recordIp] = (int)$ts;
}
}
}
// 更新當前 IP 時間戳
$records[$ip] = $now;
// 寫回文件 (獨佔鎖防併發損壞)
$fp = fopen($file, 'c+');
flock($fp, LOCK_EX);
ftruncate($fp, 0);
foreach ($records as $rip => $ts) {
fwrite($fp, "$ts\t$rip\n");
}
flock($fp, LOCK_UN);
fclose($fp);
return count($records);
}
// 使用
echo "當前在線: " . countOnline() . " 人";
HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR$now - $ts >= $timeout 的記錄fopen('c+') + flock(LOCK_EX) + ftruncate 確保原子寫入timestamp\tIP,便於解析與人工檢查// online.php
// 前端 JS
setInterval(() => {
fetch('online.php').then(r => r.text()).then(n => {
document.getElementById('online-count').textContent = n;
});
}, 30000);
SET nx ex + SCARD 或 Sorted Set (ZSET) 存儲 timestamp 作為 score