
本文介绍一种结合 cookie 与 session 的可靠方案,确保每篇文章对同一用户仅统计一次浏览量,避免页面刷新导致重复计数,兼顾安全性与实用性。
本文介绍一种结合 cookie 与 session 的可靠方案,确保每篇文章对同一用户仅统计一次浏览量,避免页面刷新导致重复计数,兼顾安全性与实用性。
在构建内容型网站(如音乐作品页、博客文章页)时,准确的“独立用户浏览量”(Unique View Count)比单纯刷新计数更有业务价值。原始代码仅依赖 $_SESSION['recent_posts'][$id],但 Session 在页面重载时仍可能未及时生效或跨请求丢失逻辑边界,导致重复更新;而纯 Cookie 方案又易被清除或伪造。因此,推荐采用 Cookie 主控 + Session 辅助的双层校验策略,既保障用户维度唯一性,又提升服务端可控性。
✅ 推荐实现方案(安全增强版)
<?php require_once '../config.php';
// 1. 安全输入过滤
$id = (int)$_GET['id'];
if ($id <= 0) {
http_response_code(400);
exit('Invalid post ID');
}
// 2. 构建唯一标识键:避免不同文章共用同一 Cookie 导致误判
$cookieKey = 'viewed_post_' . $id;
// 3. 检查用户是否已浏览过该文章(以 Cookie 为权威依据)
if (!isset($_COOKIE[$cookieKey])) {
// 4. 执行数据库更新(防 SQL 注入:使用预处理)
$sql = "UPDATE song SET count = count + 1 WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->execute([$id]);
// 5. 设置长期 Cookie(30 天),作用域为根路径,确保跨子目录有效
setcookie($cookieKey, '1', [
'expires' => time() + (86400 * 30),
'path' => '/',
'domain' => '', // 可选:指定域名增强安全性
'secure' => isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on',
'httponly'=> true,
'samesite'=> 'Lax'
]);
// 6. 同步标记到 Session(可选,用于同会话内快速判断)
if (!isset($_SESSION['recent_posts'])) {
$_SESSION['recent_posts'] = [];
}
$_SESSION['recent_posts'][$id] = true;
}
?>
⚠️ 关键注意事项
- 永远不要直接拼接 $_GET 参数到 SQL 中:原代码 $id = $_GET['id'] 存在严重 SQL 注入风险,必须强制类型转换(如 (int))或使用预处理语句(如本例所示)。
- Cookie 命名需唯一化:使用 viewed_post_{$id} 而非固定名(如 view_counted),防止多篇文章互相覆盖判断逻辑。
- Session 仅为辅助缓存:它不具备持久性,不能替代 Cookie 做长期唯一性判定;Cookie 才是跨会话识别用户的核心依据。
- 考虑隐私合规:若目标用户位于欧盟等地区,需在设置 Cookie 前获得用户明确同意(GDPR 要求)。
- 高并发场景优化:对于海量访问,可将计数暂存 Redis,定时批量写入数据库,避免频繁 UPDATE 锁表。
✅ 效果验证方式
- 访问 song.php?id=5 → 数据库 count +1;
- 刷新页面 → count 不再增加(Cookie 已存在);
- 清除浏览器 Cookie 后重访 → count 再次 +1;
- 切换文章 song.php?id=6 → 独立触发新 Cookie 和计数。
通过该方案,你将获得真正反映“独立用户触达”的浏览数据,为内容运营提供可信依据。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











