本文目录导读:

我来帮你规划一个PHP投票系统的搭建方案,这是一个相对完整的系统设计,我会从基础架构到核心功能逐步说明。
系统基础架构
环境要求
- PHP 7.4+
- MySQL 5.7+
- Web服务器:Apache/Nginx
- 推荐框架:Laravel/ThinkPHP(或原生PHP)
数据库设计
-- 投票主题表 CREATE TABLE `votes` ( `id` int(11) NOT NULL AUTO_INCREMENT, varchar(200) NOT NULL COMMENT '投票标题', `description` text COMMENT '投票描述', `type` tinyint(1) DEFAULT '0' COMMENT '0单选 1多选', `start_time` datetime NOT NULL COMMENT '开始时间', `end_time` datetime NOT NULL COMMENT '结束时间', `status` tinyint(1) DEFAULT '1' COMMENT '0关闭 1开启', `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ); -- 投票选项表 CREATE TABLE `vote_options` ( `id` int(11) NOT NULL AUTO_INCREMENT, `vote_id` int(11) NOT NULL, `option_name` varchar(100) NOT NULL COMMENT '选项名称', `votes_count` int(11) DEFAULT '0' COMMENT '得票数', `sort_order` int(3) DEFAULT '0' COMMENT '排序', PRIMARY KEY (`id`), FOREIGN KEY (`vote_id`) REFERENCES `votes`(`id`) ON DELETE CASCADE ); -- 投票记录表 CREATE TABLE `vote_records` ( `id` int(11) NOT NULL AUTO_INCREMENT, `vote_id` int(11) NOT NULL, `option_id` int(11) NOT NULL, `user_id` int(11) COMMENT '用户ID(可空,匿名投票)', `ip_address` varchar(45) COMMENT 'IP地址(防刷票)', `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `unique_vote` (`vote_id`, `user_id`, `ip_address`) );
核心功能实现
创建投票(Create.php)
<?php
// 简单原生PHP示例
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = $_POST['title'];
$options = $_POST['options']; // 数组
$type = $_POST['type'];
$start_time = $_POST['start_time'];
$end_time = $_POST['end_time'];
// 开启事务
$conn->begin_transaction();
try {
// 插入投票主表
$stmt = $conn->prepare("INSERT INTO votes (title, description, type, start_time, end_time) VALUES (?, ?, ?, ?, ?)");
$stmt->bind_param("ssiss", $title, $description, $type, $start_time, $end_time);
$stmt->execute();
$vote_id = $conn->insert_id;
// 插入选项
$stmt = $conn->prepare("INSERT INTO vote_options (vote_id, option_name, sort_order) VALUES (?, ?, ?)");
$order = 1;
foreach ($options as $option) {
$stmt->bind_param("isi", $vote_id, $option, $order++);
$stmt->execute();
}
$conn->commit();
echo json_encode(['success' => true, 'vote_id' => $vote_id]);
} catch (Exception $e) {
$conn->rollback();
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
}
投票功能(Vote.php)
<?php
function castVote($vote_id, $option_ids, $user_info) {
// 1. 验证投票是否有效
$vote = checkVoteValid($vote_id);
if (!$vote) {
return ['error' => '投票已结束或不存在'];
}
// 2. 检查是否已投票(防止重复)
if (checkAlreadyVoted($vote_id, $user_info)) {
return ['error' => '您已经投过票了'];
}
// 3. 验证选项数量(单选/多选)
if ($vote['type'] == 0 && count($option_ids) > 1) {
return ['error' => '此为单选投票'];
}
// 4. 记录投票
$conn->begin_transaction();
try {
foreach ($option_ids as $option_id) {
// 插入投票记录
$stmt = $conn->prepare("INSERT INTO vote_records (vote_id, option_id, user_id, ip_address) VALUES (?, ?, ?, ?)");
$stmt->bind_param("iiis", $vote_id, $option_id, $user_info['id'], $_SERVER['REMOTE_ADDR']);
$stmt->execute();
// 更新选项得票数
$conn->query("UPDATE vote_options SET votes_count = votes_count + 1 WHERE id = $option_id");
}
$conn->commit();
return ['success' => true];
} catch (Exception $e) {
$conn->rollback();
return ['error' => '投票失败,请重试'];
}
}
查看结果(Results.php)
<?php
// 获取投票结果
function getVoteResults($vote_id) {
$vote = $conn->query("SELECT * FROM votes WHERE id = $vote_id")->fetch_assoc();
// 获取各选项得票
$options = $conn->query("
SELECT vo.*,
(vo.votes_count / total.total_votes * 100) as percentage
FROM vote_options vo
CROSS JOIN (
SELECT SUM(votes_count) as total_votes
FROM vote_options
WHERE vote_id = $vote_id
) total
WHERE vo.vote_id = $vote_id
ORDER BY vo.sort_order
");
// 总投票人数
$total_voters = $conn->query("
SELECT COUNT(DISTINCT user_id) as voters
FROM vote_records
WHERE vote_id = $vote_id
")->fetch_assoc()['voters'];
return [
'vote' => $vote,
'options' => $options,
'total_voters' => $total_voters
];
}
前端界面示例
<!-- 投票表单 -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">投票系统</title>
<style>
.vote-container {
max-width: 600px;
margin: 20px auto;
padding: 20px;
}
.vote-item {
margin: 10px 0;
padding: 10px;
border: 1px solid #ddd;
}
.progress-bar {
height: 20px;
background: #e0e0e0;
border-radius: 10px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: #4CAF50;
transition: width 0.3s;
}
.btn-vote {
background: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="vote-container">
<!-- 投票表单 -->
<form id="voteForm" onsubmit="submitVote(event)">
<h2>你最喜欢的编程语言是?</h2>
<div class="vote-item">
<label>
<input type="radio" name="option" value="1" required>
PHP
</label>
</div>
<div class="vote-item">
<label>
<input type="radio" name="option" value="2">
JavaScript
</label>
</div>
<div class="vote-item">
<label>
<input type="radio" name="option" value="3">
Python
</label>
</div>
<button type="submit" class="btn-vote">提交投票</button>
</form>
<!-- 实时结果 -->
<div id="results">
<h3>当前结果</h3>
<div class="vote-item">
<span>PHP</span>
<div class="progress-bar">
<div class="progress-fill" style="width: 45%;">45%</div>
</div>
<span>45票</span>
</div>
<!-- 更多选项... -->
</div>
</div>
<script>
function submitVote(event) {
event.preventDefault();
const formData = new FormData(event.target);
fetch('vote.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if(data.success) {
alert('投票成功!');
loadResults(); // 刷新结果
} else {
alert(data.error || '投票失败');
}
});
}
function loadResults() {
fetch('results.php?vote_id=1')
.then(response => response.json())
.then(data => {
// 更新结果展示
updateDisplay(data);
});
}
// 自动刷新(每10秒)
setInterval(loadResults, 10000);
</script>
</body>
</html>
安全防护措施
防刷票机制
// IP限制
function checkIPLimit($vote_id) {
$ip = $_SERVER['REMOTE_ADDR'];
$time_limit = date('Y-m-d H:i:s', strtotime('-1 hour'));
$count = $conn->query("
SELECT COUNT(*) as cnt
FROM vote_records
WHERE vote_id = $vote_id
AND ip_address = '$ip'
AND created_at > '$time_limit'
")->fetch_assoc()['cnt'];
return $count < 3; // 每小时最多3次
}
// 验证码(Google reCAPTCHA)
function verifyCaptcha($token) {
$secret = 'YOUR_SECRET_KEY';
$response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=$secret&response=$token");
$data = json_decode($response);
return $data->success;
}
SQL注入防护
// 使用预处理语句
$stmt = $conn->prepare("SELECT * FROM votes WHERE id = ?");
$stmt->bind_param("i", $vote_id);
$stmt->execute();
// 输入过滤
$title = htmlspecialchars(strip_tags($_POST['title']), ENT_QUOTES, 'UTF-8');
进阶功能扩展
- 用户系统集成:对接用户登录体系,支持实名投票
- 多语言支持:使用gettext或PHP数组实现国际化
- 图表展示:集成Chart.js或ECharts生成可视化结果
- 定时任务:使用cron或Laravel Task Scheduling自动关闭投票
- 数据分析:记录投票时间分布,分析用户行为
- 导出功能:支持CSV/Excel导出投票数据
部署建议
# Nginx配置示例
server {
listen 80;
server_name vote.yourdomain.com;
root /var/www/vote-system/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
这个方案涵盖了一个完整投票系统的基本功能,根据实际需求,你可以选择使用框架(推荐Laravel)来快速开发,或者基于原生PHP构建轻量级系统,记得在生产环境中做好性能优化和安全防护。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播