Скрипт опросов на PHP и MySQLi
Ранее мы уже приводили код скрипта голосования на PHP. Теперь настало время рассмотреть более продвинутый код скрипта для голосования на PHP с использованием БД MySQLi.
Плюсом данного кода является то, что все необходимые данные хранятся в БД MySQLi в трех таблицах независимо от количества созданных опросов. В рассмотренном же ранее скрипте голосования, который не использует БД, для каждого опроса создавалось по два файла. Также представленный в данной теме скрипт сделан более наглядным и позволяет оставить голос и посмотреть результаты без перезагрузки страницы.
Пример работы предлагаемого нами скрипта голосования на PHP с использованием MySQLi БД и без перезагрузки страницы расположен ниже:
Какую CMS для сайта Вы предпочитаете?
Скрипт учитывает только один голос с одного IP адреса для каждого голосования в отдельности. Таким образом, если с указанного IP адреса голосуют первый раз, то под результатами голосования Вы увидите надпись "Ваш голос учтен!" и Ваш голос будет засчитан. При попытке повторного голосования с IP адреса, который уже принимал участие в опросе, под результатами голосования появится надпись "Вы уже голосовали!" и голос не будет засчитан.
Теперь давайте перейдем непосредственно к созданию подобного скрипта голосования на Вашем сайте. Для начала Вам понадобится создать три таблицы в MySQLi для хранения всех необходимых данных по опросам, как на скриншотах ниже:
Таблица: polls.
Таблица: poll_ip.
Таблица: poll_answer.
Для создания указанных таблиц, Вы можете воспользоваться следующим кодом:
CREATE TABLE IF NOT EXISTS `polls` (
`id` int(10) unsigned NOT NULL auto_increment, `title` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS `poll_answer` (
`id` int(10) unsigned NOT NULL auto_increment, `poll_id` int(10) unsigned NOT NULL,
`title` varchar(255) NOT NULL, `votes` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS `poll_ip` (
`id` int(10) unsigned NOT NULL auto_increment, `poll_id` int(10) unsigned NOT NULL,
`ip` int(10) unsigned NOT NULL, `date` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
Далее Вам понадобится создать файл, например, polls.php, который будет отвечать за отображение Ваших опросов.
В данный файл (polls.php), либо на уже имеющеюся у Вас страничку поместите следующий код:
<?php
$db=mysqli_connect("localhost","Логин","Пароль","Имя_БД");
$res=mysqli_query($db,"set names utf8");
$res=mysqli_fetch_array(mysqli_query($db,"SELECT max(id) FROM polls LIMIT 1"));
$poll_id=$res[0];
if (isset($_GET["poll_id"]) and is_numeric($_GET["poll_id"]) and $_GET["poll_id"]>0){
$res=mysqli_fetch_array(mysqli_query($db,"SELECT id FROM polls
WHERE id='".$_GET["poll_id"]."' LIMIT 1"));
if ($res[0]!='') $poll_id=$res[0];
}
$poll=mysqli_fetch_array(mysqli_query($db,"SELECT id,title FROM polls
WHERE id='".$poll_id."'"));
?>
<style type="text/css">
.polls{padding:10px; text-align:center; border:1px solid #EEEEEE; width:700px;}
.poll{text-align:left; display:table; width:100%; font-size:14px;}
.poll label{line-height:2;}
.votes{text-align:center; background-color:#CCCCFF; border:1px solid #0033FF;
margin:0 0 10px 0;}
</style>
<?php
echo '<div class="polls"><b>'.$poll["title"].'?</b>';
echo '<div class="poll" id="poll_'.$poll_id.'">';
$res=mysqli_query($db,"SELECT id,title FROM poll_answer
WHERE poll_id='".$poll_id."' ORDER BY id");
while ($answer=mysqli_fetch_array($res)) echo '<label><input type="radio"
name="item" value="'.$answer["id"].'">'.$answer["title"].'</label><br>';
echo '<div style="text-align:center;"><input type="submit" id="view_res"
value="Посмотреть результат">';
echo '<input type="submit" id="vote" value="Голосовать">';
echo '</div></div></div><br>';
?>
<script type="text/javascript">
$(document).ready(function(){
$(".poll input:first").prop("checked",true);
$("#vote").click(function(){
jQuery.post("polls_result.php",{poll_id:$(this).parents(".poll").attr("id").
split('_')[1], answer_id:$('input:checked').val()},rating_poll);});
$("#view_res").click(function(){
jQuery.post("polls_result.php",{poll_id:$(this).parents(".poll").attr("id").
split('_')[1]},rating_poll);});
function rating_poll(data){
$(".poll").fadeOut(500, function(){$(this).html(data).fadeIn(500);});
}
});
</script>
Обращаем Ваше внимание на то, что если у Вас на сайте не подключена библиотека jQuery, или Вы делаете отдельную страничку для опросов, то в файле polls.php Вам необходимо подключить ее следующим образом:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js">
</script>
Для того чтобы не создавать для каждого опроса свою страничку, как Вы могли заметить, мы добавили переменную $_GET["poll_id"]. Таким образом, при обращении к файлу polls.php следующим образом: polls.php?poll_id=3, будет отображен опрос с id=3.
Как говорилось ранее, скрипт голосования работает без перезагрузки странички, следовательно, нам понадобится создать еще один файл, например, polls_result.php. Данный файл будет вносить изменения в БД и выводить результаты голосования по нужному опросу.
Обращаем Ваше внимание на то, что наименование файла polls_result.php используется в предыдущем файле (polls.php), так что если Вы захотите переименовать файл polls_result.php, то следует внести изменения и в файл polls.php.
В файл polls_result.php, поместите следующий код:
<?php
if (isset($_POST["poll_id"]) and is_numeric($_POST["poll_id"])) {
$poll_id=$_POST["poll_id"];
}
else $poll_id='';
if (isset($_POST["answer_id"]) and is_numeric($_POST["answer_id"])) {
$answer_id=$_POST["answer_id"];
}
else $answer_id='';
if ($poll_id>0) {
$db=mysqli_connect("localhost","Логин","Пароль","Имя_БД");
$res=mysqli_query($db,"set names utf8");
if ($answer_id!='') {
$ip=$_SERVER['REMOTE_ADDR'];
$res=mysqli_query($db,"SELECT count(id) FROM poll_ip
WHERE poll_id='".$poll_id."' and ip=INET_ATON('".$ip."') LIMIT 1");
$number=mysqli_fetch_array($res);
if ($number[0]==0) {
$res=mysqli_query($db,"INSERT INTO poll_ip (poll_id,ip,date)
values ('".$poll_id."',INET_ATON('".$ip."'),'".time()."')");
$res=mysqli_query($db,"UPDATE poll_answer SET votes=(votes+1)
WHERE id='".$answer_id."' LIMIT 1");
$answer='Ваш голос учтен!';
}
else $answer='Вы уже голосовали!';
}
$summa=mysqli_fetch_array(mysqli_query($db,"SELECT max(votes) AS max_v, sum(votes)
AS sum_v FROM poll_answer WHERE poll_id='".$poll_id."' LIMIT 1"));
if ($summa["max_v"]==0) $summa["max_v"]=1;
$res=mysqli_query($db,"SELECT title,votes FROM poll_answer
WHERE poll_id='".$poll_id."' ORDER BY votes DESC");
while ($rating=mysqli_fetch_array($res)) {
echo '<div style="width:560px;float:left;">'.$rating["title"];
echo '<div class="votes" style="width:'.($rating["votes"]/$summa["max_v"]*560);
echo 'px;">'.$rating["votes"].'</div></div><div style="float:right;"><br>';
if ($summa["sum_v"]==0) echo '0 %</div>';
else echo round(100*$rating["votes"]/$summa["sum_v"],2).' %</div>';
}
echo '<div style="width:100%;float:left;">Голосов: <b>'.$summa["sum_v"].'</b>';
echo '<div style="color:#CC0000; text-align:center;">'.$answer.'</div></div>';
}
?>
После того, как Вы создали БД, файл опросов (polls.php) и файл, вносящий изменения в БД (polls_result.php), можно считать, что все готово, но осталось лишь самое простое - сделать админку по добавлению, изменению и удалению опросов. Для этого лучше создать отдельный файл, закрытый от других пользователей паролем (например, admin_polls.php), в который добавьте следующий код:
<?php
if (session_id()=='') session_start();
$db=mysqli_connect("localhost","Логин","Пароль","Имя_БД");
$res=mysqli_query($db,"set names utf8");
if (isset($_POST["add_poll"])) $res=mysqli_query($db,"INSERT INTO polls (title)
values ('".$_POST["new_poll"]."')");
if (isset($_POST["add_answer"])) $res=mysqli_query($db,"INSERT INTO poll_answer
(poll_id,title) values ('".$_SESSION["this_id"]."','".$_POST["new_answer"]."')");
if (isset($_POST["del_answer"])) $res=mysqli_query($db,"DELETE FROM poll_answer
WHERE id='".$_POST["del_answer_id"]."' LIMIT 1");
if (isset($_POST["del_poll"])) {
$res=mysqli_query($db,"DELETE FROM polls WHERE id='".$_SESSION["this_id"]."'");
$res=mysqli_query($db,"DELETE FROM poll_answer WHERE
poll_id='".$_SESSION["this_id"]."'");
}
if (isset($_POST["end_poll"]) or isset($_POST["del_poll"])) $_SESSION["this_id"]='';
if (isset($_POST["edit_answer"])) $res=mysqli_query($db,"UPDATE poll_answer
SET title='".$_POST["text_answer"]."' WHERE id='".$_POST["id_answer"]."'");
if (isset($_POST["edit_question"])) $res=mysqli_query($db,"UPDATE polls SET
title='".$_POST["text_question"]."' WHERE id='".$_SESSION["this_id"]."'");
if (isset($_POST["edit_poll"])) {
$res=mysqli_fetch_array(mysqli_query($db,"SELECT id FROM polls WHERE
id='".$_POST["poll_id"]."'"));
if ($res["id"]!=0) $_SESSION["this_id"]=$_POST["poll_id"];
}
if (isset($_POST["add_poll"]) or isset($_POST["add_answer"]) or
isset($_POST["edit_poll"]) or isset($_POST["edit_question"]) or
isset($_POST["edit_answer"]) or isset($_POST["del_answer"]) or
isset($_POST["del_poll"])) {header("Location: admin_polls.php");exit;}
?>
<style type="text/css">
.forms {border:1px solid #555555;background-color:#DDDDDD;padding:10px;width:440px;}
</style>
<div class="forms"><form method="POST" action="admin_polls.php">
<b>Добавить новый опрос!</b><br>
Вопрос: <input type="text" name="new_poll" maxlength="255" size="40" required>
<input type="submit" name="add_poll" value="Добавить"></form>
<form method="POST" action="admin_polls.php"><b>Редактировать опрос №</b>
<input type="text" name="poll_id" maxlength="5" size="5" required>
<input type="submit" name="edit_poll" value="Редактировать"></form></div>
<?php
if ($_SESSION["this_id"]!='') {
$res=mysqli_fetch_array(mysqli_query($db,"SELECT id,title FROM polls WHERE
id='".$_SESSION["this_id"]."'"));
echo '<div class="forms"><b>'.$res["title"].'</b> (id='.$res["id"].')<br>';
$res=mysqli_query($db,"SELECT id,title FROM poll_answer WHERE
poll_id='".$_SESSION["this_id"]."' ORDER BY id");
while ($answer=mysqli_fetch_array($res))
echo '- '.$answer["title"].' (id='.$answer["id"].')<br>';
?>
</div>
<div class="forms"><form method="POST" action="admin_polls.php">
<b>Добавить варианты ответов к опросу:</b><br>
Ответ: <input type="text" name="new_answer" maxlength="255" size="40" required>
<input type="submit" name="add_answer" value="Добавить"></form>
<form method="POST" action="admin_polls.php"><b>Изменить ответ</b>
c id= <input type="text" name="id_answer" maxlength="4" size="4" required><br>
Ответ: <input type="text" name="text_answer" maxlength="255" size="40" required>
<input type="submit" name="edit_answer" value="Изменить"></form>
<form method="POST" action="admin_polls.php"><b>Изменить вопрос на</b><br>
<input type="text" name="text_question" maxlength="255" size="47" required>
<input type="submit" name="edit_question" value="Изменить"></form>
<form method="POST" action="admin_polls.php"><b>Удалить ответ</b>
c id= <input type="text" name="del_answer_id" maxlength="4" size="4" required>
<input type="submit" name="del_answer" value="Удалить"></form>
<form method="POST" action="admin_polls.php">
<input type="submit" name="del_poll" value="Удалить текущий опрос">
<input type="submit" name="end_poll" value="Закончить редактирование">
</form></div>
<?php
}
?>
Пусть размер приведенного кода в данной теме Вас не пугает, т.к. это все-таки код для трех разных файлов, выполняющих разные функции. Если же Вы все сделали так, как написано в данной теме, то у Вас должна получиться страничка для проведения опросов на PHP и MySQLi, как в примере, продемонстрированном на данной страничке.
Перед публикацией все комментарии проходят обязательную модерацию!
Если Вы хотите задать какой-либо вопрос, то сделайте это на нашем форуме.
Таким образом, Вы сможете быстрее получить ответ на интересующий Вас вопрос.
42 строка: echo '<div style="color:#CC0000; text-align:center;">'.$answer.'</div></div>';
С чем это связано и как исправить, подскажите, пожалуйста.
1) В файле polls_result.php в самом начале присвоить переменной $answer значение 0.
2) Отключить показ предупреждений: error_reporting(0).
Ещё вопрос, как добавить модальное окно с предупреждением, что гость не выбрал ни одного пункта. Спасибо.
добавьте код:
if (typeof $('.poll input:checked').val()=="undefined") alert('Ответ не выбран!');
else
1. Что нужно добавить в код чтоб при отображении опроса если уже голосовали с определенного IP, выводился результат по данному голосованию, а не выбор вариантов и далее сообщение что вы уже голосовали?
2. Есть ли в данном скрипте защита от накрутки голосов?
2. Скрипт учитывает только один голос с одного IP адреса.
Спасибо.
1.А как возможно добавить цвет полоски результата для каждого варианта ответа при добавлении в базу?
2. Как изменить вывод результатов - хотел бы чтоб варианты ответов в одну строчку, а столбики над ними, т.е. не с низу вверх ответы как по умолчанию сейчас, а с лева на право в одной строке.
Спасибо.
При прямой ссылке на */polls.php скрипт отрабатывает и при нажатии клавиши результаты отображает их с использованием jquery.
Если на странице контента подключаю файл polls.php - отображается опрос, но при нажатии результаты или голосовать ничего не происходит - в чем может быть проблема?
P.S. можете оставить свой email для оперативного общения, буду очень признателен. Спасибо.
при подключении скрипта с помощью <?php include ("polls.php");?> все работает отлично, но выводится только второй опрос из двух созданных, я пыталась вывести первый опрос, сделав такой запрос:
<?php include ("polls.php?poll_id=1"); ?> - выдается ошибка. В каком из трех файлов и как правильно прописать, чтобы подключать разные опросы к разным страницам?
$res=mysqli_query($db,"UPDATE poll_answer SET votes=(votes+1) WHERE id='".$answer_id."' LIMIT 1");
Код votes=(votes+1) добавляет к суммарному числу голосов по единичке. Единичку можно заменить переменной, которая будет содержать любое другое число, полученное из БД.
Добавьте в базу пользователей столбец, который будет хранить "вес голоса" для каждого пользователя в отдельности. А в приведенный выше код нужно внести изменения: votes=(votes+'".$answer_weight."'), где переменная $answer_weight содержит предварительно полученное из БД значение "веса голоса" для данного пользователя.
Чтобы сделать привязку к id, замените INET_ATON('".$ip."') на $id_user, где $id_user - id пользователя в БД.
Единственный вопрос - в БД некорректно отображается IP и дата голоса.
Как с этим быть? Спасибо!
Я попыталась использовать ваш код для создания опросов, но у меня сейчас есть одна проблемка.
Когда кликаю на добавить, страничка admin_polls.php просто обновляется и больше ничего.
Подскажите, пожалуйста, где я могла ошибаться.
Спасибо!
Далее нужно в поле "Редактировать опрос №" ввести 1 (или другую цифру в зависимости от того, какой опрос будете редактировать) и нажать на кнопку "Редактировать".
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at X:\home\localhost\www\raschet\admin_polls.php:20) in X:\home\localhost\www\raschet\admin_polls.php on line 21
Вы можете явно указать номер опроса, например, $poll_id=2;
Помогите! Я не понимаю что делать.
Проверьте, чтобы в файле admin_polls.php до строчки if (session_id()=='') session_start(); не было никаких служебных символов или тегов кроме "<?php".
В самом 1111.php
<?php $banners = array (); ?>
<?php $banners[] = '1'; ?>
<?php $banners[] = '2'; ?>
<?php $banners[] = '3'; ?>
<?php $_GET["poll_id"]=$banners[array_rand ($banners)]; include ("polls.php"); ?>
=====
$banners[] = '1'; - это айди опроса, в данном случае в ротации опросы с айди 1,2,3 (можно сколько угодно опросов добавить)
Наверное через одно место, но работает, может кому пригодится.
$res=mysqli_fetch_array(mysqli_query($db,"SELECT max(id) FROM polls LIMIT 1"));// вот тут показано, что выбирается по максимальному id.
А по поводу вопроса про рандом, посмотрите тут: http://usefulscript.ru/forum/showthread.php?tid=374
echo '<div class="poll" id="poll_id'.$poll_id.'">';//так было у меня, почему я так сделал, сам понять не могу.
echo '<div class="poll" id="poll_'.$poll_id.'">';//так правильно.
Короче говоря, я сам себе злобный буратино.
<?php $_GET["poll_id"]=1; include ("polls.php"); ?>
<?php $_GET["poll_id"]=2; include ("polls.php"); ?>
, при нажатии кнопки результат голосования в первом и во втором опросе открывается один и тот же результат.