首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP + 文字檔實現無資料庫線上投票系統完整教學

     編輯:PHP 綜合知識

前言

中小型投票活動若不想架設資料庫,採用 PHP + 文字檔 是輕量級替代方案。本文提供完整原始碼,包含前端表單、後端邏輯、結果顯示與長條圖視覺化,並說明關鍵安全性考量。

系統架構

  • index.html:投票表單 (單選項目、送出按鈕、查看結果連結)
  • survey.php:核心邏輯 (驗證、寫入、讀取、顯示結果)
  • data.txt:投票選項清單 (每行一項)
  • survey.txt:投票統計與 IP 記錄 (格式:票數1|票數2|...|IP1|IP2|...)
  • smilies/:長條圖圖片素材 (0.gif, 1.gif... 或自訂)

核心程式碼:survey.php

<?php
header('Content-Type: text/html; charset=UTF-8');

$dataFile = 'data.txt';      // 選項檔
$voteFile = 'survey.txt';    // 統計檔

// 讀取選項
$options = file($dataFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if (!$options) die('找不到投票選項檔案');

// 讀取統計資料
$voteData = file($voteFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$statsLine = $voteData[0] ?? str_repeat('0|', count($options));
$votes = explode('|', trim($statsLine, '|'));

// 確保陣列長度一致
$votes = array_pad($votes, count($options), 0);

// 已投票 IP 記錄 (從第 2 行開始)
$votedIPs = array_slice($voteData, 1);
$clientIP = $_SERVER['REMOTE_ADDR'];

// 處理投票動作
if (isset($_POST['go']) && $_POST['go'] === '1') {
    $choice = (int) ($_POST['vote'] ?? -1);
    
    // 驗證選項有效性
    if ($choice < 0 || $choice >= count($options)) {
        die('無效的投票選項');
    }
    
    // 防重複投票 (簡易 IP 檢查)
    if (in_array($clientIP, $votedIPs)) {
        die("<center><font color='red'>您已投過票,感謝參與!</font></center>");
    }
    
    // 寫入統計
    $votes[$choice]++;
    $newStats = implode('|', $votes) . "\n" . implode("\n", array_merge([$clientIP], $votedIPs));
    file_put_contents($voteFile, $newStats, LOCK_EX);
    
    // 導向結果頁 (避免重複提交)
    header('Location: survey.php?result=1');
    exit;
}

// 顯示結果模式
if (isset($_GET['result'])) {
    $totalVotes = array_sum($votes);
    echo "<table cellpadding='10' border='1'>";
    
    foreach ($options as $i => $option) {
        $count = (int) $votes[$i];
        $percent = $totalVotes > 0 ? ($count / $totalVotes * 100) : 0;
        $barWidth = (int) ($percent * 3); // 放大倍率可調
        
        echo "<tr>";
        echo "<td><b>" . htmlspecialchars($option) . "</b></td>";
        echo "<td><img src='smilies/bar.gif' height='20' width='{$barWidth}' align='middle'> ";
        echo sprintf("%.1f%%", $percent) . "</td>";
        echo "<td align='center'>{$count} 票</td>";
        echo "</tr>";
    }
    
    echo "</table><p>總投票數:{$totalVotes}</p>";
    exit;
}

// 顯示投票表單
?>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>線上投票</title></head>
<body>
<form method="post" action="survey.php">
    <?php foreach ($options as $i => $opt): ?>
    <p><input type="radio" name="vote" value="<?= $i ?>"> <?= htmlspecialchars($opt) ?></p>
    <?php endforeach; ?>
    <input type="hidden" name="go" value="1">
    <p><input type="submit" value="送出投票"></p>
</form>
<p><a href="survey.php?result=1">查看結果</a></p>
</body>
</html>

資料檔案範例

data.txt

最喜歡的程式語言
最常用的框架
偏好的資料庫
最愛的編輯器
常用的作業系統

survey.txt (自動生成)

12|8|15|20|5
192.168.1.100
192.168.1.101
...

關鍵安全性與限制說明

風險現狀改善建議
重複投票IP 檢查 (同 NAT 下用戶誤判)加入 Cookie/Session 二次驗證、要求登入
競態條件file_put_contents(..., LOCK_EX)高併發改用 SQLite/Redis 原子操作
XSS 注入輸出已用 htmlspecialchars()選項內容若含 HTML 需額外淨化
資料完整性文字檔易損壞定期備份、改用 JSON 結構化儲存
投票刷票無防禦驗證碼、頻率限制、用戶認證

進階擴充方向

  • 多選投票:表單改用 checkbox,後端陣列處理
  • 截止時間:在 data.txt 首行加入 expire=2024-12-31,投票前檢查
  • 結果匯出:新增 export=csv 參數輸出 CSV
  • 管理後台:簡易密碼保護頁面可編輯選項、重置統計
  • 圖表美化:引入 Chart.js、Google Charts 繪製互動式圖表

總結

文字檔投票系統部署簡單、零依賴,適合內部活動、小型問卷、教學示範。生產環境若需高併發、嚴格防刷、複雜權限,請遷移至資料庫方案 (MySQL/SQLite) 或第三方投票服務 (Google Forms, Typeform)。核心邏輯:讀取 → 驗證 → 原子寫入 → 視覺化,掌握此流程即可舉一反三。


延伸閱讀:PHP 檔案操作與鎖定機制、PHP 陣列操作技巧大全、Web 安全基礎:XSS 與 CSRF 防護

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved