Голосование на php. Бесповоротный

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

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

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

Итак, первое что понадобиться — форма для отображения пунктов голосования и передачи результатов на сервер соответствующему скрипту для сохранения. Сразу выделяются два новых объекта — скрипт для приема, обработки и сохранения результатов и место для хранения этих самых результатов голосования.

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

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

Как Вам мой сайт?
Супер!
Хорошо
Нормально
Слабо
Лажа!

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

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

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

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

Я уже молчу про недоработанный алгоритм скрипта — посмотрите в первой части мы очень неплохо используем цикл, который не зависит от количества пунктов голосования, а вот при выводе результатов — мы жестко привязаны к этому числу. А вывод результатов? Куда это годиться…

В общем, продолжать перечислять недостатки скрипта можно долго.

Хорошо Плохо

Бывает необходимым организовать на сайте систему голосования пользователей. Например, это может быть система голосования за товары на сайте-каталоге и организация рейтинга товаров в соответствии с числом поданных голосов. Рассмотрим пошагово, как написать скрипт голосования.

1. Скрипт голосования на сайте удобно разместить в отдельном файле, например, votes.php. Наш скрипт должен создавать таблицу базы данных о голосах за каждый конкретный товар, таблица создаётся автоматически при первом голосовании за данный товар. Ведь не заставлять же администраторов сайта-каталога создавать таблицу вручную при внесении в каталог каждого нового товара! Таблица содержит поля, ответственные за идентификационный номер голоса, идентификационный номер товара, собственно переменной, обозначающей, что голос подан (можно придать ей значение "1", строки с этими полями затем подсчитываются при формировании рейтинга), IP пользователя (но можно и без него), ник пользователя и категорию товара.

Код PHP/MySQL

mysql_query ("CREATE TABLE IF NOT EXISTS votes_$cid (

vid int(10) NOT NULL auto_increment,

id int(10) NOT NULL,

pluss int(10) NOT NULL,

ip_addr char(50) NOT NULL,

nick varchar(255) NOT NULL,

dat_lim date NOT NULL,

cid int(10) NOT NULL,

PRIMARY KEY(vid)

) ENGINE=MyISAM DEFAULT CHARSET=utf8") Or die (mysql_error ());

Показанная в коде выше конструкция автоматического создания таблицы является предметом вопроса в .

Пусть на сайте голосовать имеют возможность лишь зарегистрированные пользователи, можно установить ограничение голосования по дате, установить суточный лимит голосования за тот или иной товар (это всё на случаи, если есть подозрения в "накрутке голосов"), а также открывать голосование лишь спустя некоторое время после появления товара в каталоге, а также устанавливать дату окончания голосования, если этого требует конкретная бизнес-логика.

2. В нашем скрипте должна происходить проверка, отправлены ли данные из формы, то есть, нажал ли посетитель каталога кнопку "голосовать" (за это отвечает переменная $_POST["sended"] со значением "yes"). Далее - проверка, является ли проголосовавший зарегистрированным пользователем ($rights>0). Если есть необходимость завершить голосование за тот или иной товар к определённой дате - проверка, не завершено ли голосование ($end_dat

Код PHP

if ($_POST["sended"]=="yes")

if ($rights>0)

if ($row01==0)

$dat=date ("Y-m-d H:i:s");

if ($end_dat

elseif ($dat

3. Если в соответствии с датой голосовать можно, выполняется блок голосования. Однако в его начале происходит проверка, не исчерпан ли суточный лимит голосования за данный товар, а также проверка на случай, если голосование ещё не открыто. Если всё в порядке и голосовать можно, данные заносятся в базу, в ту её таблицу, которая содержит данные о голосовании за данный товар (таблица votes_$cid). Далее путём нового запроса к этой же таблице подсчитывается число голосов (строк) за товар с данным id. Затем в таблицу с данными обо всех товарах (goods) соответственно id товара записывается обновлённое число строк, каждая из которых означает один голос за данный товар.

Код PHP

if ($end_dat

elseif ($dat

if ($row11

if ($v_cl==1)

elseif ($v_cl==0)

4. А ниже показано, что предусматривает программа в случае отрицательных ответов на обозначенные выше вопросы.

Код PHP

else

else

else

else

echo "It`snt OK";

5. И, наконец полный код блока, реализующего голосование. Нужно только перед показанным кодом сделать проверку (if (isset ...)), существуют ли значения переменных, переданных из формы для голосования в наш скрипт. А в самом верху разместить запрос к базе на создание новой таблицы (самый первый фрагмент кода)

Код PHP

$result01=mysql_query ("SELECT * FROM votes_$cid WHERE nick="$nick" AND id="$id"") or die (mysql_error ());

$row01 = mysql_num_rows ($result01);

$resultT=mysql_query ("select voting_closed,end_ FROM categories WHERE cid="$cid"") or die (mysql_error ());

$myrowT=mysql_fetch_array ($resultT);

$end_dat = $myrowT;

$v_cl = $myrowT;

$dat_new=date ("Y-m-d");

$resultL1=mysql_query ("select * FROM votes_$cid WHERE dat_lim="$dat_new" AND id="$id"") or die (mysql_error ());

$row11 = mysql_num_rows ($resultL1);

if ($_POST["sended"]=="yes")

if ($rights>0)

if ($row01==0)

$dat=date ("Y-m-d H:i:s");

if ($end_dat

elseif ($dat

if ($row11

if ($v_cl==1)

elseif ($v_cl==0)

$result1=mysql_query ("INSERT INTO votes_$cid

(id,ip_addr,nick,pluss,dat_lim,cid)

VALUES ("$id","$ip_addr","$nick","$pluss","$dat_new","$cid")");

$result2=mysql_query ("SELECT * FROM votes_$cid WHERE id="$id"") or die (mysql_error ());

$row2=mysql_num_rows ($result2);

$result3=mysql_query ("UPDATE goods SET votes="$row2" WHERE id="$id"");

else

else

else

else

echo "It`snt OK";

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

Здравствуйте. Предлагаю Вашему вниманию инструкцию по созданию системы голосования на сайте.
Итак, давайте рассмотрим, что же представляет из себя система голосования на сайте.
Пользователь видит на странице форму, в которой присутствуют заголовок голования, варианты ответов, из которых можно выбрать один, тот, за который пользователь хочет проголосовать.
После выбора пользователь нажимает кнопку "проголосовать" и система засчитывает его голос в пользу того или иного варианта ответа.
"Снаружи" вроде всё просто: обычная форма, обычная кнопка, обычные radio-кнопки. Но давайте заглянем "за кулисы" работы скрипта голосования. Там нашему взору откроется более интересная картина.

Что же представляет из себя система голосования изнутри?
Как можно запоминать выбор пользователя и не давать ему голосовать повторно?
Как создавать вопросы и варианты ответов?
На эти вопросы мы сейчас попробуем получить развёрнутый ответ. Нам нужно где-то хранить вопросы и варианты ответов. Для этого нам потребуется создать базу данных MySQL и пару таблиц в ней.
Давайте создадим такие таблицы:
voting - таблица, в которой будут храниться вопросы и варианты ответов.
voted - таблица, в которой будут храниться выбранные варианты ответов и IP адреса проголосовавших.

В таблице voting нам нужно создать три поля:
1. id - тип INTEGER, AUTOINCREMENT.
В поле будет содержаться идентификатор вопросов и ответов.
2. parent_id - тип INTEGER.
В поле будет содержаться идентификатор родительской записи (т.е. по отношению к ответам, родительской записью будет вопрос).
3. title - тип VARCHAR.
В поле будет содержаться текст вопросов и ответов.

Как видите, мы будем хранить вопросы и ответы в одной таблице. Поскольку нам в данном случае нужна связь один-ко-многим и поля, необходимые для хранения вопросов и ответов одинаковые,- это очень удобный вариант.
Тут плюс в том, что не нужно создавать отдельные таблицы для вопросов и ответов, и запросов в БД нужно будет делать меньше.

В таблице voted нам нужно создать два поля:
1. answer_id - тип INTEGER.
В поле будет содержаться идентификатор выбранного пользователем ответа (т.е. ответа, за который он проголосовал).
2. ip - тип VARCHAR. UNIQUE.
В поле будет содержаться IP-адрес пользователя, который проголосовал. В данном поле будут только уникальные значения IP.

На этом моменте остановимся поподробнее. Почему мы запоминаем IP пользователя? Ведь IP бывают динамическими, скажете Вы. И пользователь, сменив IP, сможет проголосовать несколько раз. Я с Вами полностью согласен, но ещё не придумано 100% надёжного варианта запонимания неавторизованного пользователя.
Почему я упомянул авторизацию: если мы хотим, чтобы пользователь гарантированно не смог проголосовать несколько раз, нам нужно сделать систему авторизации и заместо IP пользователя использовать для учёта его голоса идентификатор его аккаунта.
И сделать открытым голосование только для авторизованных пользователей. Но создание голосования для авторизованных не входит в планы данной статьи, поэтому для учёта голоса будем запоминать IP.

Итак, мы создали таблицы, теперь давайте перейдём непосредственно к реализации php-скрипта системы голосования. Давайте разберём вот такой класс:

"/>


Как мы видим, в коде проводится проверка, голосовали ли пользователь ранее:


Если пользователь уже голосовал (т.е. его IP есть в таблице voted ), то ему выводится на экран статистика голосов, т.е. ответы и количество пользователей, проголосовавших за тот или иной ответ. Тут Вы можете подключить фантазию и доработать скрипт, например, сделав вывод статистики в виде графика.
Если же пользователь не принимал участие в данном голосовании, то ему выводится форма, в которой он может выбрать необходимый вариант ответа и проголосовать за него.
В цикле мы проходим по всем вариантам ответов и выводим их на экран. В качестве значения в поля "radio" вставляются их идентификаторы: