如何在PHP MySQL投票系统中防止用户重复投票?
我看了你当前基于Session的防重复投票代码,要切换成Cookie方案其实很简单——Cookie存在客户端,能在用户关闭浏览器后仍保留投票记录(你可以自定义过期时长),下面是修改后的完整代码,我会标注关键改动:
修改后的PHP逻辑
<?php session_start(); include 'functions.php'; // Connect to MySQL $pdo = pdo_connect_mysql(); // 如果存在投票ID参数 if (isset($_GET['id'])) { $pollId = (string)$_GET['id']; // 检查Cookie中是否已有该投票的记录 if(isset($_COOKIE['voted']) && in_array($pollId, explode(',', $_COOKIE['voted']))){ die('Your vote is already considered.'); } // 获取投票详情 $stmt = $pdo->prepare('SELECT * FROM polls WHERE id = ?'); $stmt->execute([$_GET['id']]); $poll = $stmt->fetch(PDO::FETCH_ASSOC); if ($poll) { // 获取投票选项 $stmt = $pdo->prepare('SELECT * FROM poll_answers WHERE poll_id = ?'); $stmt->execute([$_GET['id']]); $poll_answers = $stmt->fetchAll(PDO::FETCH_ASSOC); // 用户提交投票 if (isset($_POST['poll_answer'])) { // 更新投票数 $stmt = $pdo->prepare('UPDATE poll_answers SET votes = votes + 1 WHERE id = ?'); $stmt->execute([$_POST['poll_answer']]); // --- 核心改动:设置Cookie记录投票行为 --- // 读取已有投票记录(如果存在) $existingVotes = isset($_COOKIE['voted']) ? $_COOKIE['voted'] : ''; // 追加当前投票ID到记录中 $newVotes = $existingVotes ? $existingVotes . ',' . $pollId : $pollId; // 设置Cookie,有效期30天,根目录生效(全站可访问) setcookie('voted', $newVotes, time() + (86400 * 30), "/"); // 跳转至结果页 header ('Location: result.php?id=' . $_GET['id']); exit; } } else { die ('Poll with that ID does not exist.'); } } else { die ('No poll ID specified.'); } ?>
前端代码(无需改动)
<?=template_header('Poll Vote')?> <div class="content poll-vote"> <h2><?=$poll['title']?></h2> <p><?=$poll['des']?></p> <form action="vote.php?id=<?=$_GET['id']?>" method="post"> <?php for ($i = 0; $i < count($poll_answers); $i++): ?> <label> <input type="radio" name="poll_answer" value="<?=$poll_answers[$i]['id']?>"<?=$i == 0 ? ' checked' : ''?>> <?=$poll_answers[$i]['title']?> </label> <?php endfor; ?> <div> <input type="submit" value="Vote"> <a href="result.php?id=<?=$poll['id']?>">View Result</a> </div> </form> </div> <?=template_footer()?>
关键改动说明
- Cookie检查逻辑:把原来的Session判断换成了Cookie检查,通过将多个投票ID用逗号分隔存在一个Cookie中,实现单Cookie记录多投票状态。
- 投票后设置Cookie:在用户成功提交投票后,将当前投票ID追加到Cookie里,设置30天有效期(你可以自行调整,比如
time() + 3600就是1小时),路径设为/确保全站都能读取这个Cookie。 - 移除Session依赖:因为切换到了Cookie方案,所以删除了原来的
$_SESSION['voted']相关代码。
注意事项
- Cookie存储在客户端,用户可以手动清除Cookie绕过限制,如果需要更严格的防重复,建议结合数据库记录用户IP(但IP也可能存在共享情况)。
- 确保
setcookie函数在任何HTML输出之前调用,否则会因为HTTP头已发送而报错。
内容的提问来源于stack exchange,提问作者bob011
相关产品推荐
相关产品推荐

