Php实现投票系统
数据库设计
创建一个MySQL数据库表来存储投票选项和投票记录。需要两个表:一个存储选项信息,另一个记录用户投票。
CREATE TABLE `poll_options` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`option_text` varchar(255) NOT NULL,
`vote_count` int(11) DEFAULT 0,
PRIMARY KEY (`id`)
);
CREATE TABLE `poll_votes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`option_id` int(11) NOT NULL,
`user_ip` varchar(45) DEFAULT NULL,
`vote_time` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
KEY `option_id` (`option_id`)
);
连接数据库
使用PDO连接MySQL数据库,确保在config.php中设置正确的数据库凭据。
// config.php
define('DB_HOST', 'localhost');
define('DB_NAME', 'poll_db');
define('DB_USER', 'username');
define('DB_PASS', 'password');
// db_connect.php
try {
$pdo = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
创建投票表单
生成包含投票选项的HTML表单,从数据库动态加载选项。
// poll_form.php
$stmt = $pdo->query("SELECT * FROM poll_options");
$options = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo '<form action="vote.php" method="post">';
foreach($options as $option) {
echo '<div class="option">';
echo '<input type="radio" name="vote" value="'.$option['id'].'" id="option'.$option['id'].'">';
echo '<label for="option'.$option['id'].'">'.$option['option_text'].'</label>';
echo '</div>';
}
echo '<button type="submit">Submit Vote</button>';
echo '</form>';
处理投票提交
验证并处理用户提交的投票,防止重复投票。
// vote.php
session_start();
if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['vote'])) {
$option_id = (int)$_POST['vote'];
$user_ip = $_SERVER['REMOTE_ADDR'];
// 检查是否已投票
$stmt = $pdo->prepare("SELECT * FROM poll_votes WHERE user_ip = ?");
$stmt->execute([$user_ip]);
if($stmt->rowCount() === 0) {
// 记录投票
$pdo->beginTransaction();
try {
$insert = $pdo->prepare("INSERT INTO poll_votes (option_id, user_ip) VALUES (?, ?)");
$insert->execute([$option_id, $user_ip]);
$update = $pdo->prepare("UPDATE poll_options SET vote_count = vote_count + 1 WHERE id = ?");
$update->execute([$option_id]);
$pdo->commit();
$_SESSION['voted'] = true;
header("Location: results.php");
} catch(Exception $e) {
$pdo->rollBack();
die("Vote processing failed: ".$e->getMessage());
}
} else {
die("You have already voted!");
}
}
显示投票结果
计算并显示投票结果,可以使用文本或图表形式展示。
// results.php
$stmt = $pdo->query("SELECT * FROM poll_options");
$options = $stmt->fetchAll(PDO::FETCH_ASSOC);
$total = 0;
foreach($options as $option) {
$total += $option['vote_count'];
}
echo '<div class="results">';
foreach($options as $option) {
$percent = ($total > 0) ? round(($option['vote_count'] / $total) * 100) : 0;
echo '<div class="result-item">';
echo '<div class="option-text">'.$option['option_text'].'</div>';
echo '<div class="progress-bar" style="width: '.$percent.'%">'.$percent.'%</div>';
echo '</div>';
}
echo '</div>';
防止重复投票
使用多种方法防止用户重复投票,包括IP检查、Cookie和会话控制。
// 检查会话
if(isset($_SESSION['voted'])) {
die("You have already voted in this session!");
}
// 检查Cookie
if(isset($_COOKIE['poll_voted'])) {
die("You have already voted (cookie detected)!");
} else {
setcookie('poll_voted', '1', time()+86400); // 24小时
}
// IP检查已在投票处理中实现
管理后台
创建简单的管理界面,允许添加新的投票选项。
// admin.php
if(isset($_POST['new_option'])) {
$option_text = trim($_POST['new_option']);
if(!empty($option_text)) {
$insert = $pdo->prepare("INSERT INTO poll_options (option_text) VALUES (?)");
$insert->execute([$option_text]);
}
}
echo '<form method="post">';
echo '<input type="text" name="new_option" placeholder="New option text">';
echo '<button type="submit">Add Option</button>';
echo '</form>';
安全增强
实施额外的安全措施,防止SQL注入和跨站脚本攻击。
// 对所有用户输入进行过滤
$option_id = filter_input(INPUT_POST, 'vote', FILTER_VALIDATE_INT);
if($option_id === false || $option_id === null) {
die("Invalid vote option!");
}
// 使用预处理语句防止SQL注入
// 已在前面代码中实现
// 输出转义
function escape($data) {
return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
}
// 使用时:
echo escape($user_input);





