Голосование на PHP

Один из самых частых вопросов начинающих веб-программистов является вопрос "Как сделать онлайн голосование?". Очень просто! И даже если сейчас вам так не кажется, уверяю вас, стоит лишь вдумчиво прочитать данную статью, и вы забудете про вопросы о голосованиях раз и навсегда.

Предисловие: если вдруг вы являетесь не новичком в PHP, советую не кидать статью, дочитав до середины, чертыхаясь на автора, а прочитать данный небольшой материал полностью.

Для начала давайте определимся, что нам нужно для создания голосования.

Итак, первое что понадобится — форма для отображения пунктов голосования и передачи результатов на сервер соответствующему скрипту для сохранения. Сразу выделяются два новых объекта — скрипт для приема, обработки и сохранения результатов и место для хранения этих самых результатов голосования. Местом для хранения данных спокойно может быть обычный файл. Чего-то не хватает? Ах, да! Нам же нужно ещё отображать результаты голосования. Эту функцию можно спокойно исполнить в нашем едином скрипте.

Ну что же, приступим. Начнем, конечно же, с формы для отображения пунктов голосования и передачи данных на сервер. В ней нет ничего сложного:

<form method="post" action="golos.php">
    <table border="1">
        <tr><td>
            <table>
                <tr><td>Как вам мой сайт?</td></tr>
                <tr><td><input type="radio" name="otvet" value="1">Супер!</td></tr>
                <tr><td><input type="radio" name="otvet" value="2">Хорошо</td></tr>
                <tr><td><input type="radio" name="otvet" value="3">Нормально</td></tr>
                <tr><td><input type="radio" name="otvet" value="4">Слабо</td></tr>
                <tr><td><input type="radio" name="otvet" value="5">Лажа!</td></tr>
                <tr><td>
                    <input type="submit" name="golos" value="Голосовать">
                    <input type="submit" name="result" value="Результаты">
                </td></tr>
            </table>
        </td></tr>
    </table>
</form>

Как вы видите, обычная форма, которая передает данные методом POST скрипту golos.php, имеется 5 вариантов ответа, кнопка "Голосовать" для голосования и "Результаты" — просмотр результатов голосования без участия в самом голосовании.

Пример формы голосования

Что дальше? Скрипт? Нет, в начале нужно определиться, как мы будем хранить данные. Первое, что приходит в голову — в каждой строке по значению. Довольно удобно — все сразу можно считать в массив. Однако не стоит забывать, что при этом первая строка примет индекс 0 — тут начинающие программисты часто путаются. Я советую не использовать первую строку для хранения результатов голосования, а написать там какой-нибудь комментарий, например, что это файл для хранения результатов такого-то голосования.

Самое время перейти к скрипту голосования. Он не такой тяжелый, так что я напишу весь скрипт сразу, а уже в нем буду давать комментарии каждой строчке.

<?php
    // Имя файла с результатами голосования:
    $file = "golos.dat";
    // Считываем данные голосования в массив:
    $a = file($file);
    // Инициализируем переменные:
    $i = 1;
    $n = 0;
    // Получаем количество элементов в массиве голосований:
    $fi = Count($a);
    // В цикле обрабатываем каждый элемент массива:
    while ($i <= $fi):
        // Удаляем переносы строк:
        $a[$i] = trim(str_replace ("\n","", $a[$i]));
        // Считаем количество голосов:
        $n = $n + $a[$i];
        $i++;
    endwhile;

    // Если был дан голос:
    if ($otvet != "") {
        // Выводим соответствующее сообщение:
        echo "<br>Спасибо, Ваш голос принят";
        // Увеличиваем на 1 соответствующий пункт голосования:
        $a[$otvet]++;
        // И общее количество голосов:
        $n++;

        // Подготавливаем данные для записи в файл:
        $rez = "Опрос на сайте - это комментарий в файле\n" . $a[1] . "\n" . $a[2] . "\n" . $a[3] . "\n" . $a[4];
        // Открываем файл для записи:
        $fp = @fopen($file, "w");
        // Если успешно:
        if ($fp) {
            // Записываем данные в файл:
            fputs($fp, $rez);
            // И закрываем его:
            fclose($fp);
        }
        // Если произошла ошибка:
        else {
            echo "Ошибка при открытии файла";
        }
    }
    // Выводим результаты:
    else {
        echo "<br>Результаты голосования";
    }
    echo "<br>Супер! — <b>" . $a[1] . "</b>";
    echo "<br>Хорошо — <b>" . $a[2] . "</b>";
    echo "<br>Нормально — <b>" . $a[3] . "</b>";
    echo "<br>Слабо — <b>" . $a[4] . "</b>";
    echo "<br>Лажа! — <b>" . $a[5] . "</b>";
    echo "<br><br>Всего голосов: " . $n;
?>

Сразу скажу, что данный скрипт я нашел в кодах одного из моих знакомых, считающего себя большим спецом. Данный скрипт стоит у него на сайте.

Ну что же. Вот и все! Вы уже побежали ставить себе на сайт голосование? А зря! Ведь данный код лишь демонстрация алгоритма, слабого алгоритма, я уже молчу про возможности самого кода. Он даже не сможет обеспечить надежной работы - при большом количестве обращений файл голосований будет периодически обнуляться. Или, например, у нас нет абсолютно никакой защиты от многократных голосований - один человек может голосовать столько раз, сколько ему захочется. Я уже молчу про недоработанный алгоритм скрипта - посмотрите в первой части мы очень неплохо используем цикл, который не зависит от количества пунктов голосования, а вот при выводе результатов - мы жестко привязаны к этому числу. А вывод результатов? Куда это годиться...

В общем, продолжать перечислять недостатки скрипта можно долго. Давайте лучше я покажу, как можно от них избавиться на примере моего скрипта для голосований. Но это уже в продолжении статьи. Следите за новинками. Если не хотите пропустить - советую подписаться на рассылку сайта: тут.