You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP MySQL投票系统中防止用户重复投票?

用Cookie实现投票防重复功能

我看了你当前基于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()?>

关键改动说明

  1. Cookie检查逻辑:把原来的Session判断换成了Cookie检查,通过将多个投票ID用逗号分隔存在一个Cookie中,实现单Cookie记录多投票状态。
  2. 投票后设置Cookie:在用户成功提交投票后,将当前投票ID追加到Cookie里,设置30天有效期(你可以自行调整,比如time() + 3600就是1小时),路径设为/确保全站都能读取这个Cookie。
  3. 移除Session依赖:因为切换到了Cookie方案,所以删除了原来的$_SESSION['voted']相关代码。

注意事项

  • Cookie存储在客户端,用户可以手动清除Cookie绕过限制,如果需要更严格的防重复,建议结合数据库记录用户IP(但IP也可能存在共享情况)。
  • 确保setcookie函数在任何HTML输出之前调用,否则会因为HTTP头已发送而报错。

内容的提问来源于stack exchange,提问作者bob011

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 10:27:36