php 实现投票功能
数据库设计
创建投票相关的数据表结构,通常需要 votes(投票主表)和 vote_options(投票选项表)两张表。
CREATE TABLE votes (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
description TEXT,
start_time DATETIME,
end_time DATETIME,
status TINYINT DEFAULT 1 COMMENT '1:进行中 0:已结束'
);
CREATE TABLE vote_options (
id INT AUTO_INCREMENT PRIMARY KEY,
vote_id INT NOT NULL,
option_text VARCHAR(255) NOT NULL,
vote_count INT DEFAULT 0,
FOREIGN KEY (vote_id) REFERENCES votes(id)
);
创建投票表单
构建前端投票表单页面,使用 HTML 和 PHP 混合编写。
<?php
// 连接数据库
$db = new PDO('mysql:host=localhost;dbname=vote_system', 'username', 'password');
// 获取投票信息
$voteId = $_GET['vote_id'] ?? 0;
$stmt = $db->prepare("SELECT * FROM votes WHERE id = ? AND status = 1");
$stmt->execute([$voteId]);
$vote = $stmt->fetch();
// 获取选项
$optionsStmt = $db->prepare("SELECT * FROM vote_options WHERE vote_id = ?");
$optionsStmt->execute([$voteId]);
$options = $optionsStmt->fetchAll();
?>
<form action="vote_submit.php" method="post">
<input type="hidden" name="vote_id" value="<?php echo $voteId; ?>">
<h3><?php echo htmlspecialchars($vote['title']); ?></h3>
<?php foreach ($options as $option): ?>
<label>
<input type="radio" name="option_id" value="<?php echo $option['id']; ?>">
<?php echo htmlspecialchars($option['option_text']); ?>
</label><br>
<?php endforeach; ?>
<button type="submit">提交投票</button>
</form>
处理投票提交
创建处理投票提交的 PHP 脚本。

<?php
session_start();
// 防止重复投票
if (isset($_SESSION['voted_' . $_POST['vote_id']])) {
die('您已经投过票了');
}
// 连接数据库
$db = new PDO('mysql:host=localhost;dbname=vote_system', 'username', 'password');
// 验证投票有效性
$voteId = $_POST['vote_id'];
$optionId = $_POST['option_id'];
$stmt = $db->prepare("SELECT 1 FROM votes WHERE id = ? AND status = 1");
$stmt->execute([$voteId]);
if (!$stmt->fetch()) {
die('投票不存在或已结束');
}
// 更新票数
$updateStmt = $db->prepare("UPDATE vote_options SET vote_count = vote_count + 1 WHERE id = ? AND vote_id = ?");
$updateStmt->execute([$optionId, $voteId]);
// 标记已投票
$_SESSION['voted_' . $voteId] = true;
header('Location: vote_result.php?vote_id=' . $voteId);
显示投票结果
创建显示投票结果的页面。
<?php
// 连接数据库
$db = new PDO('mysql:host=localhost;dbname=vote_system', 'username', 'password');
// 获取投票信息
$voteId = $_GET['vote_id'] ?? 0;
$stmt = $db->prepare("SELECT * FROM votes WHERE id = ?");
$stmt->execute([$voteId]);
$vote = $stmt->fetch();
// 获取选项及票数
$optionsStmt = $db->prepare("SELECT * FROM vote_options WHERE vote_id = ?");
$optionsStmt->execute([$voteId]);
$options = $optionsStmt->fetchAll();
// 计算总票数
$totalVotes = array_sum(array_column($options, 'vote_count'));
?>
<h3><?php echo htmlspecialchars($vote['title']); ?> - 投票结果</h3>
<?php foreach ($options as $option): ?>
<div>
<strong><?php echo htmlspecialchars($option['option_text']); ?></strong>
<div>
票数: <?php echo $option['vote_count']; ?>
<?php if ($totalVotes > 0): ?>
(<?php echo round($option['vote_count'] / $totalVotes * 100, 2); ?>%)
<?php endif; ?>
</div>
<div style="background: #eee; height: 20px; width: <?php echo $totalVotes > 0 ? ($option['vote_count'] / $totalVotes * 100) : 0; ?>%"></div>
</div>
<?php endforeach; ?>
<p>总票数: <?php echo $totalVotes; ?></p>
安全增强措施
实现 IP 限制和验证码等安全措施。

// IP限制
$ip = $_SERVER['REMOTE_ADDR'];
$ipStmt = $db->prepare("SELECT 1 FROM vote_logs WHERE vote_id = ? AND ip = ?");
$ipStmt->execute([$voteId, $ip]);
if ($ipStmt->fetch()) {
die('该IP已投票');
}
// 验证码检查
if ($_POST['captcha'] !== $_SESSION['captcha']) {
die('验证码错误');
}
// 投票后记录IP
$logStmt = $db->prepare("INSERT INTO vote_logs (vote_id, ip, voted_at) VALUES (?, ?, NOW())");
$logStmt->execute([$voteId, $ip]);
定时任务处理
使用 Cron 定时检查并更新过期投票状态。
<?php
// 连接数据库
$db = new PDO('mysql:host=localhost;dbname=vote_system', 'username', 'password');
// 更新过期投票状态
$updateStmt = $db->prepare("UPDATE votes SET status = 0 WHERE end_time < NOW() AND status = 1");
$updateStmt->execute();
将此脚本设置为每天运行的 Cron 任务:
0 0 * * * /usr/bin/php /path/to/update_vote_status.php






