首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 實作簡易流量統計器(總訪問、今日、昨日)

     編輯:PHP 綜合知識

資料表設計

CREATE TABLE mycounter (
  id INT PRIMARY KEY DEFAULT 1,  -- 單列計數器,固定 id=1
  total_visits BIGINT UNSIGNED NOT NULL DEFAULT 0,
  today_visits INT UNSIGNED NOT NULL DEFAULT 0,
  yesterday_visits INT UNSIGNED NOT NULL DEFAULT 0,
  record_date DATE NOT NULL,      -- 最後統計日期
  UNIQUE KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO mycounter (id, record_date) VALUES (1, CURDATE());

核心統計邏輯(單一檔案版,含 Cookie 去重)

<?php
session_start();

// 1. 連線資料庫(建議用 PDO)
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

// 2. 讀取計數器
$stmt = $pdo->query('SELECT * FROM mycounter WHERE id = 1');
$row = $stmt->fetch();

// 3. 判斷是否跨日
$today = date('Y-m-d');
$isNewDay = ($row['record_date'] !== $today);

if ($isNewDay) {
    // 歸檔昨日、歸零今日
    $pdo->prepare('UPDATE mycounter SET yesterday_visits = today_visits, today_visits = 0, record_date = ? WHERE id = 1')
        ->execute([$today]);
    $row['today_visits'] = 0;
    $row['yesterday_visits'] = $row['today_visits']; // 注意:這裡已更新,實際應先存舊值
}

// 4. 訪客去重:以 Cookie 標記「今日已計數」
$cookieName = 'visit_counted';
$counted = isset($_COOKIE[$cookieName]);

if (!$counted) {
    // 原子遞增
    $pdo->prepare('UPDATE mycounter SET total_visits = total_visits + 1, today_visits = today_visits + 1 WHERE id = 1')
        ->execute();
    $row['total_visits']++;
    $row['today_visits']++;

    // 設定 Cookie 過期至今日 23:59:59
    $expire = strtotime('today 23:59:59');
    setcookie($cookieName, '1', $expire, '/', '', false, true); // Secure, HttpOnly
}

// 5. 顯示
echo "總訪問量:{$row['total_visits']}<br>";
echo "今日流量:{$row['today_visits']}<br>";
echo "昨日流量:{$row['yesterday_visits']}<br>";
?>

效能與擴展建議

  • 高併發:單表單列 `UPDATE ... + 1` 會產生行鎖爭用。改用 Redis `INCR` 計數,定時同步落地 MySQL。
  • 分佈式:多台 Web 伺服器共用 Redis,Key 設計 `counter:total`、`counter:today:{date}`。
  • 精確去重:Cookie 可被清除/偽造。進階方案用「用戶 ID + 日期」唯一索引寫入 `visit_log` 表,`INSERT IGNORE` 成功才計數。
  • 排除爬蟲:解析 `User-Agent`、IP 信譽庫,過濾已知 Bot 流量。

Redis 版本核心片段

<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$todayKey = 'counter:today:' . date('Ymd');
$totalKey = 'counter:total';

$isNew = !$redis->exists($todayKey);
if ($isNew) {
    $redis->set($todayKey, 0);
    $redis->expire($todayKey, 86400 * 2);
}

$visitorKey = 'visitor:' . md5($_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']) . ':' . date('Ymd');
if (!$redis->exists($visitorKey)) {
    $redis->incr($totalKey);
    $redis->incr($todayKey);
    $redis->set($visitorKey, 1, 86400);
}

echo "總計:{$redis->get($totalKey)} | 今日:{$redis->get($todayKey)}";
?>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved