如何修改现有Hit Counter实现日/周/月/年访问量统计功能?
改造Hit Counter实现多维度访问统计
没问题,我帮你把现有的Hit Counter改成支持按日、周、月、年展示访问量的版本,咱们一步步来:
第一步:更新数据库表结构
你原来的counter表只能存一个总访问数,没法按时间维度统计,所以得换个更灵活的表结构——咱们创建一个按日存储访问量的表,这样后续统计周、月、年数据都能通过聚合查询实现:
-- 如果不需要保留原来的总计数表,可以先删除(记得备份数据!) DROP TABLE IF EXISTS `counter`; -- 创建新的按日统计访问表 CREATE TABLE `daily_hits` ( `date` DATE NOT NULL PRIMARY KEY, -- 存储日期(格式:YYYY-MM-DD) `hits` INT(20) NOT NULL DEFAULT 0 -- 当天的访问次数 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
*小提示:*如果想保留总访问数,可以不用删旧表,后续在计数逻辑里同时更新旧表和新表就行。
第二步:修改PHP计数逻辑
原来的代码只是简单累加总计数,现在要改成按日累加——每次访问时,先检查当天是否已有记录,有就加1,没有就新增一条记录:
<?php // 替换成你的数据库连接信息 $dbHost = 'localhost'; $dbName = '你的数据库名'; $dbUser = '你的用户名'; $dbPass = '你的密码'; // 设置PHP时区,避免日期统计出错(根据你的地区调整) date_default_timezone_set('Asia/Shanghai'); try { // 初始化PDO数据库连接 $pdo = new PDO( "mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] ); // 获取当前日期(YYYY-MM-DD) $today = date('Y-m-d'); // 检查今日是否已有访问记录 $checkStmt = $pdo->prepare("SELECT hits FROM daily_hits WHERE date = :today"); $checkStmt->bindParam(':today', $today); $checkStmt->execute(); $exists = $checkStmt->fetch(PDO::FETCH_ASSOC); if ($exists) { // 已有记录,累加访问次数 $updateStmt = $pdo->prepare("UPDATE daily_hits SET hits = hits + 1 WHERE date = :today"); $updateStmt->bindParam(':today', $today); $updateStmt->execute(); } else { // 无记录,新增今日的初始访问量(1次) $insertStmt = $pdo->prepare("INSERT INTO daily_hits (date, hits) VALUES (:today, 1)"); $insertStmt->bindParam(':today', $today); $insertStmt->execute(); } } catch (PDOException $e) { // 错误处理,生产环境建议写入日志而非直接输出 echo "数据库错误:" . $e->getMessage(); } ?>
第三步:实现多维度统计展示
现在可以通过SQL聚合查询,拿到你需要的各种维度数据,然后按你想要的格式输出:
<?php // 继续上面的数据库连接代码... // 1. 今日访问量 $todayStmt = $pdo->prepare("SELECT hits FROM daily_hits WHERE date = CURDATE()"); $todayStmt->execute(); $todayHits = $todayStmt->fetchColumn() ?: 0; // 2. 昨日访问量 $yesterdayStmt = $pdo->prepare("SELECT hits FROM daily_hits WHERE date = DATE_SUB(CURDATE(), INTERVAL 1 DAY)"); $yesterdayStmt->execute(); $yesterdayHits = $yesterdayStmt->fetchColumn() ?: 0; // 3. 上月访问量 $lastMonthStmt = $pdo->prepare("SELECT SUM(hits) FROM daily_hits WHERE DATE_FORMAT(date, '%Y-%m') = DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 1 MONTH), '%Y-%m')"); $lastMonthStmt->execute(); $lastMonthHits = $lastMonthStmt->fetchColumn() ?: 0; // 4. 近3个月的月度统计(比如四月、三月、二月) $recentMonthsStmt = $pdo->prepare(" SELECT DATE_FORMAT(date, '%Y-%m') AS month, SUM(hits) AS total_hits FROM daily_hits WHERE date >= DATE_SUB(CURDATE(), INTERVAL 3 MONTH) GROUP BY DATE_FORMAT(date, '%Y-%m') ORDER BY date DESC "); $recentMonthsStmt->execute(); $recentMonths = $recentMonthsStmt->fetchAll(PDO::FETCH_ASSOC); // 定义月份中文映射 $monthMap = [ 'January' => '一月', 'February' => '二月', 'March' => '三月', 'April' => '四月', 'May' => '五月', 'June' => '六月', 'July' => '七月', 'August' => '八月', 'September' => '九月', 'October' => '十月', 'November' => '十一月', 'December' => '十二月' ]; // 拼接输出内容 $output = "今日 - {$todayHits}次、昨日 - {$yesterdayHits}次、上月 - {$lastMonthHits}次"; foreach ($recentMonths as $monthData) { $englishMonth = date('F', strtotime($monthData['month'])); $chineseMonth = $monthMap[$englishMonth]; $output .= "、{$chineseMonth} - {$monthData['total_hits']}次"; } // 输出最终统计 echo $output; ?>
补充说明:
- 如果需要周统计,可以用类似这样的SQL:
SELECT SUM(hits) FROM daily_hits WHERE WEEK(date) = WEEK(CURDATE()) - 1 AND YEAR(date) = YEAR(CURDATE())(统计上周的总访问量) - 如果需要年统计,可以用
SELECT SUM(hits) FROM daily_hits WHERE YEAR(date) = YEAR(CURDATE()) - 1(统计去年的总访问量)
内容的提问来源于stack exchange,提问作者kc melec
相关产品推荐
相关产品推荐

