Категории

Простой скрипт голосования без базы данных

17.12.2025 | коды из категории: Создание сайтов

про Простой скрипт голосования без базы данных

пока не проверял

Небольшой PHP-скрипт для создания опросов, где все данные хранятся в обычных текстовых файлах — без необходимости настраивать SQLite, MySQL или другие СУБД. Подходит для личных блогов, технических сайтов или самописных движков.

Что умеет:

Как устроен:

Всё хранится в двух файлах:

Плюс служебный файл .pollhash — он нужен, чтобы понять, изменился ли опрос, и при необходимости очистить старые голоса.

Почему без базы?

Если вам не нужна сложная аналитика, авторизация или тысячные нагрузки — зачем тащить полноценную БД? Файловое хранилище проще в развёртывании, отладке и резервном копировании. Особенно удобно на самописных сайтах или при хостинге на мини-ПК (например, ARM64 с SSD).

Безопасность

Скрипт использует сессии PHP, чтобы один пользователь не мог проголосовать дважды за сессию. Это не защита от ботов, но достаточно для личного блога или внутреннего использования. При желании можно легко добавить лимит по IP или CAPTCHA.

Как использовать

  1. Скачайте два файла: index.php и config.php
  2. Загрузите их в отдельную папку на сервер с PHP
  3. Убедитесь, что папка доступна для записи (chmod 755 или 775)
  4. Откройте страницу в браузере — опрос заработает сразу
  5. Чтобы поменять тему — отредактируйте config.php

структура:

/poll/
├── index.php
├── config.php          ← варианты ответов
├── votes.txt           ← сюда записываются голоса (создаётся автоматически)
└── (ничего больше не нужно)

config.php — тут задаёшь новый опрос вручную

<?php
// Просто редактируешь этот файл, чтобы создать новый опрос
return [
    'question' => 'В чём проблема?',
    'description' => 'Поделитесь своим опытом :',
    'options' => [
        'Проверка  системы',
        'Охлаждание системы',
        'Настройка системый',
        'Восстановение Windows',
        'Замена материнской платы',
        'Настройка режима БИОС',
        'Замена кабеля ',
        'Другое'
    ]
];

index.php — основной файл

<?php
session_start();

// Загружаем настройки опроса
$config = require __DIR__ . '/config.php';
$options = $config['options'];
$question = $config['question'];
$description = $config['description'];

$votesFile = __DIR__ . '/votes.txt';

// Если структура опроса изменилась — сбросим голоса
$hashFile = __DIR__ . '/.pollhash';
$currentHash = md5(json_encode($options));

if (file_exists($hashFile)) {
    $savedHash = file_get_contents($hashFile);
    if ($savedHash !== $currentHash) {
        // Опрос изменился — очищаем голоса
        file_put_contents($votesFile, '');
        file_put_contents($hashFile, $currentHash);
    }
} else {
    file_put_contents($hashFile, $currentHash);
    if (!file_exists($votesFile)) {
        touch($votesFile);
    }
}

// Чтение всех голосов
$rawVotes = file($votesFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$voteCounts = array_fill(0, count($options), 0);

foreach ($rawVotes as $line) {
    $idx = (int)$line;
    if ($idx >= 0 && $idx < count($options)) {
        $voteCounts[$idx]++;
    }
}

$totalVotes = array_sum($voteCounts);

// Обработка голоса
if ($_POST['option'] ?? false) {
    $choice = (int)$_POST['option'];
    
    if ($choice >= 0 && $choice < count($options) && !isset($_SESSION['voted'])) {
        file_put_contents($votesFile, $choice . PHP_EOL, FILE_APPEND | LOCK_EX);
        $_SESSION['voted'] = true;
        // Перезагружаем данные
        $voteCounts[$choice]++;
        $totalVotes++;
        
        header("Location: " . $_SERVER['PHP_SELF']);
        exit;
    }
}

// Отмечаем, что пользователь уже зашёл (даже если не голосовал)
$_SESSION['visited'] = true;
?>
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <title><?= htmlspecialchars($question) ?></title>
  <style>
    body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; max-width: 650px; margin: 20px auto; padding: 0 15px; }
    h2 { margin-bottom: 10px; }
    p.desc { color: #555; margin-bottom: 20px; }
    .option { margin: 12px 0; }
    .bar-container { display: flex; align-items: center; margin-top: 4px; }
    .bar { height: 20px; background: #4CAF50; border-radius: 2px; }
    .percent { margin-left: 10px; color: #555; font-size: 0.9em; }
    button { background: #2196F3; color: white; border: none; padding: 6px 12px; border-radius: 4px; cursor: pointer; }
    button:disabled { background: #ccc; }
  </style>
</head>
<body>

<h2><?= htmlspecialchars($question) ?></h2>
<p class="desc"><?= htmlspecialchars($description) ?></p>

<?php if (!empty($_SESSION['voted'])): ?>
    <p><strong>✅ Спасибо за ваш голос!</strong></p>
<?php endif; ?>

<form method="POST">
  <?php foreach ($options as $i => $text):
      $percent = $totalVotes ? round(100 * $voteCounts[$i] / $totalVotes, 1) : 0;
  ?>
    <div class="option">
      <?php if (empty($_SESSION['voted'])): ?>
        <label>
          <input type="radio" name="option" value="<?= $i ?>" required>
          <?= htmlspecialchars($text) ?>
        </label>
        <br>
      <?php else: ?>
        <strong><?= htmlspecialchars($text) ?></strong>
      <?php endif; ?>

      <div class="bar-container">
        <div class="bar" style="width: <?= min(100, $percent) ?>%;"></div>
        <span class="percent"><?= $percent ?>%</span>
      </div>
    </div>
  <?php endforeach; ?>

  <?php if (empty($_SESSION['voted'])): ?>
    <button type="submit">Проголосовать</button>
  <?php endif; ?>
</form>

<p style="font-size:0.85em; color:#888; margin-top:30px;">
  Всего голосов: <?= $totalVotes ?>
</p>

</body>
</html>

Комментарии

Пока нет комментариев. Будьте первым!

Оставить комментарий

← Назад к списку

Посетителей сегодня: 0


кто я | о блоге

© Digital Specialist | Не являемся сотрудниками Google, Яндекса и NASA