php 实现投票系统
创建数据库表结构
设计一个简单的投票系统数据库表,包含投票主题和选项。以下为MySQL示例:
CREATE TABLE polls (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE poll_options (
id INT AUTO_INCREMENT PRIMARY KEY,
poll_id INT,
option_text VARCHAR(255) NOT NULL,
vote_count INT DEFAULT 0,
FOREIGN KEY (poll_id) REFERENCES polls(id)
);
CREATE TABLE poll_votes (
id INT AUTO_INCREMENT PRIMARY KEY,
poll_id INT,
option_id INT,
user_ip VARCHAR(45),
voted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (poll_id) REFERENCES polls(id),
FOREIGN KEY (option_id) REFERENCES poll_options(id)
);
连接数据库
使用PDO建立数据库连接:
$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("Connection failed: " . $e->getMessage());
}
创建投票功能
实现添加新投票的功能:
function createPoll($title, $description, $options) {
global $pdo;
$stmt = $pdo->prepare("INSERT INTO polls (title, description) VALUES (?, ?)");
$stmt->execute([$title, $description]);
$pollId = $pdo->lastInsertId();
foreach ($options as $option) {
$stmt = $pdo->prepare("INSERT INTO poll_options (poll_id, option_text) VALUES (?, ?)");
$stmt->execute([$pollId, $option]);
}
return $pollId;
}
显示投票界面
获取并显示投票内容:
function displayPoll($pollId) {
global $pdo;
$pollStmt = $pdo->prepare("SELECT * FROM polls WHERE id = ?");
$pollStmt->execute([$pollId]);
$poll = $pollStmt->fetch();
$optionsStmt = $pdo->prepare("SELECT * FROM poll_options WHERE poll_id = ?");
$optionsStmt->execute([$pollId]);
$options = $optionsStmt->fetchAll();
echo "<h3>{$poll['title']}</h3>";
echo "<p>{$poll['description']}</p>";
echo "<form method='post' action='vote.php'>";
echo "<input type='hidden' name='poll_id' value='{$poll['id']}'>";
foreach ($options as $option) {
echo "<div><input type='radio' name='option_id' value='{$option['id']}' id='option{$option['id']}'>";
echo "<label for='option{$option['id']}'>{$option['option_text']}</label></div>";
}
echo "<button type='submit'>Vote</button>";
echo "</form>";
}
处理投票逻辑
记录投票并防止重复投票:
function processVote($pollId, $optionId) {
global $pdo;
$userIp = $_SERVER['REMOTE_ADDR'];
// 检查是否已投票
$checkStmt = $pdo->prepare("SELECT * FROM poll_votes WHERE poll_id = ? AND user_ip = ?");
$checkStmt->execute([$pollId, $userIp]);
if ($checkStmt->rowCount() > 0) {
return false; // 已投票
}
// 记录投票
$voteStmt = $pdo->prepare("INSERT INTO poll_votes (poll_id, option_id, user_ip) VALUES (?, ?, ?)");
$voteStmt->execute([$pollId, $optionId, $userIp]);
// 更新选项计数
$updateStmt = $pdo->prepare("UPDATE poll_options SET vote_count = vote_count + 1 WHERE id = ?");
$updateStmt->execute([$optionId]);
return true;
}
显示投票结果
展示投票统计结果:
function displayResults($pollId) {
global $pdo;
$optionsStmt = $pdo->prepare("
SELECT po.*,
(po.vote_count / (SELECT SUM(vote_count) FROM poll_options WHERE poll_id = ?) * 100) as percentage
FROM poll_options po
WHERE poll_id = ?
ORDER BY vote_count DESC
");
$optionsStmt->execute([$pollId, $pollId]);
$options = $optionsStmt->fetchAll();
echo "<h3>Voting Results</h3>";
foreach ($options as $option) {
echo "<div>{$option['option_text']}: {$option['vote_count']} votes (".round($option['percentage'], 2)."%)</div>";
echo "<div style='background:#eee; height:20px; width:".$option['percentage']."%;'></div>";
}
}
安全防护措施
增强系统安全性:
// 防止SQL注入
所有数据库查询都应使用预处理语句
// 限制投票频率
function canUserVote($pollId) {
global $pdo;
$ip = $_SERVER['REMOTE_ADDR'];
$stmt = $pdo->prepare("SELECT COUNT(*) FROM poll_votes WHERE poll_id = ? AND user_ip = ? AND voted_at > DATE_SUB(NOW(), INTERVAL 1 DAY)");
$stmt->execute([$pollId, $ip]);
return $stmt->fetchColumn() == 0;
}
// 验证输入数据
function validateInput($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
完整示例流程
典型的使用流程:
// 创建新投票
$options = ['Option 1', 'Option 2', 'Option 3'];
$pollId = createPoll('Favorite Color', 'What is your favorite color?', $options);
// 显示投票
displayPoll($pollId);
// 处理投票
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['poll_id'], $_POST['option_id'])) {
$success = processVote($_POST['poll_id'], $_POST['option_id']);
if ($success) {
echo "Thank you for voting!";
} else {
echo "You have already voted in this poll.";
}
}
// 显示结果
displayResults($pollId);
这个实现包含了基本的投票系统功能,可以根据需要进一步扩展,如添加用户认证、多选投票、截止日期等功能。







