php 实现投票系统
创建数据库表结构
设计一个简单的投票系统数据库,包含投票主题和选项表。使用MySQL示例:
CREATE TABLE votes (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
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)
);
连接数据库
使用PDO连接MySQL数据库:
$host = 'localhost';
$dbname = 'voting_system';
$username = 'root';
$password = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
创建投票表单
构建前端投票表单:
<form method="post" action="vote.php">
<h3><?php echo htmlspecialchars($voteTitle); ?></h3>
<?php foreach ($options as $option): ?>
<label>
<input type="radio" name="vote_option" value="<?php echo $option['id']; ?>">
<?php echo htmlspecialchars($option['option_text']); ?>
</label><br>
<?php endforeach; ?>
<input type="hidden" name="vote_id" value="<?php echo $voteId; ?>">
<button type="submit">Submit Vote</button>
</form>
处理投票提交
处理投票逻辑并防止重复投票:
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$voteId = $_POST['vote_id'];
$optionId = $_POST['vote_option'];
// 检查用户是否已投票
if (!isset($_SESSION['voted_'.$voteId])) {
// 更新投票计数
$stmt = $pdo->prepare("UPDATE vote_options SET vote_count = vote_count + 1 WHERE id = ?");
$stmt->execute([$optionId]);
// 标记用户已投票
$_SESSION['voted_'.$voteId] = true;
$message = "Vote submitted successfully!";
} else {
$message = "You have already voted in this poll.";
}
}
显示投票结果
生成投票结果可视化:
$stmt = $pdo->prepare("SELECT option_text, vote_count FROM vote_options WHERE vote_id = ?");
$stmt->execute([$voteId]);
$options = $stmt->fetchAll(PDO::FETCH_ASSOC);
$totalVotes = array_sum(array_column($options, 'vote_count'));
foreach ($options as $option) {
$percentage = $totalVotes > 0 ? ($option['vote_count'] / $totalVotes) * 100 : 0;
echo '<div>';
echo '<span>'.htmlspecialchars($option['option_text']).'</span>';
echo '<div style="background:#ddd;height:20px;width:'.$percentage.'%"></div>';
echo '<span>'.$option['vote_count'].' votes ('.round($percentage,1).'%)</span>';
echo '</div>';
}
安全增强措施
实施额外的安全防护:
// 验证输入
$voteId = filter_input(INPUT_POST, 'vote_id', FILTER_VALIDATE_INT);
$optionId = filter_input(INPUT_POST, 'vote_option', FILTER_VALIDATE_INT);
// 检查选项是否属于该投票
$stmt = $pdo->prepare("SELECT id FROM vote_options WHERE id = ? AND vote_id = ?");
$stmt->execute([$optionId, $voteId]);
if (!$stmt->fetch()) {
die("Invalid vote option");
}
// 使用CSRF令牌
if (empty($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die("Invalid CSRF token");
}
管理员功能
添加创建新投票的功能:

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['create_vote'])) {
$title = $_POST['title'];
$options = explode("\n", $_POST['options']);
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("INSERT INTO votes (title) VALUES (?)");
$stmt->execute([$title]);
$voteId = $pdo->lastInsertId();
foreach ($options as $option) {
$option = trim($option);
if (!empty($option)) {
$stmt = $pdo->prepare("INSERT INTO vote_options (vote_id, option_text) VALUES (?, ?)");
$stmt->execute([$voteId, $option]);
}
}
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
throw $e;
}
}






