Главная / Веб-программирование / Онлайн-опрос и голосования с помощью PHP и MySQL

Онлайн-опрос и голосования с помощью PHP и MySQL

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

В этой статье мы рассмотрим, как с помощью PHP создать простой скрипт опроса. Он использует PHP и MySQL для хранения в БД вариантов ответа, данных опроса и принятых голосов.

Функционал скрипта опроса

Данные опроса и варианты ответов хранятся в базе MySQL. Вопрос и варианты ответа будут извлекаться из базы данных, и выводиться пользователю. Он может выбрать вариант и отдать свой голос. Результаты голосования будут сохранены в базе данных с соответствующим вариантом ответа.

Кроме этого мы будем использовать PHP COOKIE, чтобы ограничить возможность повторного голосования. Результат опроса с общим подсчетом голосов и их количеством для каждого варианта ответа будут отображаться на странице. Результаты по вариантам ответа будут отображаться в виде процентной диаграммы.

Создание таблиц базы данных

В базе данных MySQL скрипта для голосования на сайте три таблицы: polls, poll_options и poll_votes.

Таблица polls содержит тему опроса или вопрос:

CREATE TABLE `polls` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`subject` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
`status` enum(‘1′,’0’) COLLATE utf8_unicode_ci NOT NULL DEFAULT ‘1’,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Таблица poll_options содержит варианты ответа и соответствующий идентификатор опроса:

CREATE TABLE `poll_options` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`poll_id` int(11) NOT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
`status` enum(‘1′,’0’) COLLATE utf8_unicode_ci NOT NULL DEFAULT ‘1’,
PRIMARY KEY (`id`),
KEY `poll_id` (`poll_id`),
CONSTRAINT `poll_options_ibfk_1` FOREIGN KEY (`poll_id`) REFERENCES `polls` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Таблица poll_votes содержит результат подсчета голосов для варианта ответа, соответствующий идентификатор варианта ответа и идентификатор опроса:

CREATE TABLE `poll_votes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`poll_id` int(11) NOT NULL,
`poll_option_id` int(11) NOT NULL,
`vote_count` bigint(10) NOT NULL,
PRIMARY KEY (`id`),
KEY `poll_id` (`poll_id`),
KEY `poll_option_id` (`poll_option_id`),
CONSTRAINT `poll_votes_ibfk_1` FOREIGN KEY (`poll_id`) REFERENCES `polls` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT `poll_votes_ibfk_2` FOREIGN KEY (`poll_option_id`) REFERENCES `poll_options` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Вставьте данные опроса и соответствующие варианты ответа в демонстрационную базу данных скрипта голосования:

INSERT INTO `polls` (`id`, `subject`, `created`, `modified`, `status`) VALUES
(1, ‘Which is Your Favorite Website for PHP Programming?’, ‘2016-11-07 04:13:13’, ‘2016-11-07 04:13:13’, ‘1’);
INSERT INTO `poll_options` (`id`, `poll_id`, `name`, `created`, `modified`, `status`) VALUES
(1, 1, ‘CodexWorld’, ‘2016-11-07 11:29:31’, ‘2016-11-07 11:29:31’, ‘1’),
(2, 1, ‘SitePoint’, ‘2016-11-07 11:29:31’, ‘2016-11-07 11:29:31’, ‘1’),
(3, 1, ‘Envato Tuts+’, ‘2016-11-07 11:29:31’, ‘2016-11-07 11:29:31’, ‘1’),
(4, 1, ‘Others’, ‘2016-11-08 08:20:25’, ‘2016-11-08 08:20:25’, ‘1’);

Класс Poll

Класс Poll используется для обработки запроса ко всей системе голосования и опросов. Этот класс выполняет следующие действия.

__construct() — подключает и выбирает базу данных.

getQuery() — выполняет SQL-запрос к базе данных MySQL и возвращает данные. Это закрытая функция, используемая только в этом классе.

getPolls() — получает опрос и соответствующие варианты ответа. Кроме этого он может получать данные нескольких опросов на основе запроса.

vote() — добавляет или обновляет количество полученных голосов в базе данных.

getResult() – эта функция PHP скрипта голосования предоставляет результаты опроса с количеством полученных голосов по каждому из вариантов ответа.

<?php
/*
* Управляющий класс Poll
* Этот класс используется для управления системой онлайн опросов и голосований
* @author CodexWorld.com
* @url http://www.codexworld.com
* @license http://www.codexworld.com/license
*/
class Poll{
private $dbHost = ‘localhost’;
private $dbUser = ‘root’;
private $dbPwd = »;
private $dbName = ‘poll_system’;
private $db = false;
private $pollTbl = ‘polls’;
private $optTbl = ‘poll_options’;
private $voteTbl = ‘poll_votes’;

public function __construct(){
if(!$this->db){
// Устанавливаем соединение с базой данных
$conn = new mysqli($this->dbHost, $this->dbUser, $this->dbPwd, $this->dbName);
if($conn->connect_error){
die("Failed to connect with MySQL: " . $conn->connect_error);
}else{
$this->db = $conn;
}
}
}

/*
* Выполняем запрос к базе данных
* @param строка SQL
* @param строка count, single, all
*/
private function getQuery($sql,$returnType = »){
$data = »;
$result = $this->db->query($sql);
if($result){
switch($returnType){
case ‘count’:
$data = $result->num_rows;
break;
case ‘single’:
$data = $result->fetch_assoc();
break;
default:
if($result->num_rows > 0){
while($row = $result->fetch_assoc()){
$data[] = $row;
}
}
}
}
return !empty($data)?$data:false;
}

/*
* Получаем данные опроса
* Возвращаем данные одного или нескольких вопросов вместе с соответствующими им вариантами ответов
* @param строка single, all
*/
public function getPolls($pollType = ‘single’){
$pollData = array();
$sql = "SELECT * FROM ".$this->pollTbl." WHERE status = ‘1’ ORDER BY created DESC";
$pollResult = $this->getQuery($sql, $pollType);
if(!empty($pollResult)){
if($pollType == ‘single’){
$pollData[‘poll’] = $pollResult;
$sql2 = "SELECT * FROM ".$this->optTbl." WHERE poll_id = ".$pollResult[‘id’]." AND status = ‘1’";
$optionResult = $this->getQuery($sql2);
$pollData[‘options’] = $optionResult;
}else{
$i = 0;
foreach($pollResult as $prow){
$pollData[$i][‘poll’] = $prow;
$sql2 = "SELECT * FROM ".$this->optTbl." WHERE poll_id = ".$prow[‘id’]." AND status = ‘1’";
$optionResult = $this->getQuery($sql2);
$pollData[$i][‘options’] = $optionResult;
}
}
}
return !empty($pollData)?$pollData:false;
}

/*
* Подтверждаем ответ
* @param массив вариантов ответов
*/
public function vote($data = array()){
if(!isset($data[‘poll_id’]) || !isset($data[‘poll_option_id’]) || isset($_COOKIE[$data[‘poll_id’]])) {
return false;
}else{
$sql = "SELECT * FROM ".$this->voteTbl." WHERE poll_id = ".$data[‘poll_id’]." AND poll_option_id = ".$data[‘poll_option_id’];
$preVote = $this->getQuery($sql, ‘count’);
if($preVote > 0){
$query = "UPDATE ".$this->voteTbl." SET vote_count = vote_count+1 WHERE poll_id = ".$data[‘poll_id’]." AND poll_option_id = ".$data[‘poll_option_id’];
$update = $this->db->query($query);
}else{
$query = "INSERT INTO ".$this->voteTbl." (poll_id,poll_option_id,vote_count) VALUES (".$data[‘poll_id’].",".$data[‘poll_option_id’].",1)";
$insert = $this->db->query($query);
}
return true;
}
}

/*
* Получаем результаты опроса
* @param ID опроса
*/
public function getResult($pollID){
$resultData = array();
if(!empty($pollID)){
$sql = "SELECT p.subject, SUM(v.vote_count) as total_votes FROM ".$this->voteTbl." as v LEFT JOIN ".$this->pollTbl." as p ON p.id = v.poll_id WHERE poll_id = ".$pollID;
$pollResult = $this->getQuery($sql,’single’);
if(!empty($pollResult)){
$resultData[‘poll’] = $pollResult[‘subject’];
$resultData[‘total_votes’] = $pollResult[‘total_votes’];
$sql2 = "SELECT o.id, o.name, v.vote_count FROM ".$this->optTbl." as o LEFT JOIN ".$this->voteTbl." as v ON v.poll_option_id = o.id WHERE o.poll_id = ".$pollID;
$optResult = $this->getQuery($sql2);
if(!empty($optResult)){
foreach($optResult as $orow){
$resultData[‘options’][$orow[‘name’]] = $orow[‘vote_count’];
}
}
}
}
return !empty($resultData)?$resultData:false;
}
}

Представление опроса (index.php)

В этом файле скрипта голосование с выводом результатов отображается вопрос опроса и соответствующие варианты ответа. Для выбора варианта используется радио-кнопка. Внизу выводится кнопка «Отправить» и ссылка для просмотра результатов опроса:

<?php
//Получаем данные опроса и вариантов ответов
$pollData = $poll->getPolls();
?>
<div class="pollContent">
<?php echo !empty($statusMsg)?'<p class="stmsg">’.$statusMsg.'</p>’:»; ?>
<form action="" method="post" name="pollFrm">
<h3><?php echo $pollData[‘poll’][‘subject’]; ?></h3>
<ul>
<?php foreach($pollData[‘options’] as $opt){
echo ‘<li><input type="radio" name="voteOpt" value="’.$opt[‘id’].’" >’.$opt[‘name’].'</li>’;
} ?>
</ul>
<input type="hidden" name="pollID" value="<?php echo $pollData[‘poll’][‘id’]; ?>">
<input type="submit" name="voteSubmit" class="button" value="Vote">
<a href="results.php?pollID=<?php echo $pollData[‘poll’][‘id’]; ?>">Results</a>
</form>
</div>

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

<?php
//Включаем и инициализируем класс Poll
include ‘Poll.php’;
$poll = new Poll;

//Проверяем, отправлен ли ответ
if(isset($_POST[‘voteSubmit’])){
$voteData = array(
‘poll_id’ => $_POST[‘pollID’],
‘poll_option_id’ => $_POST[‘voteOpt’] );
//Оправляем результаты опроса с помощью класса Poll
$voteSubmit = $poll->vote($voteData);
if($voteSubmit){
//храним в $_COOKIE, чтобы отметить, что пользователь уже проголосовал
setcookie($_POST[‘pollID’], 1, time()+60*60*24*365);
$statusMsg = ‘Your vote has been submitted successfully.’;
}else{
$statusMsg = ‘Your vote already had submitted.’;
}
}
?>

Результаты опроса (results.php)

В этом файле скрипта социального голосования для сайта результаты опроса извлекаются из базы данных и отображаются пользователю. Количество голосов для каждого варианта ответа преобразуется в процентный формат и выводится в виде процентной диаграммы:

<?php
// Включаем и инициализируем класс class
include ‘Poll.php’;
$poll = new Poll;
?>
<?php
//Получаем данные результатов опроса
$pollResult = $poll->getResult($_GET[‘pollID’]);
?>
<h3><?php echo $pollResult[‘poll’]; ?></h3>
<p><b>Total Votes:</b> <?php echo $pollResult[‘total_votes’]; ?></p>
<?php
if(!empty($pollResult[‘options’])){ $i=0;
//Массив цветов столбцов для каждого варианта ответа
$barColorArr = array(‘azure’,’emerald’,’violet’,’yellow’,’red’);
//Общие параметры столбцов для вариантов ответа
foreach($pollResult[‘options’] as $opt=>$vote){
//Вычисляем процентное соотношение для каждого варианта ответа
$votePercent = round(($vote/$pollResult[‘total_votes’])*100);
$votePercent = !empty($votePercent)?$votePercent.’%’:’0%’;
//Определяем цвет столбца
if(!array_key_exists($i, $barColorArr)){
$i=0;
}
$barColor = $barColorArr[$i];
?>
<div class="bar-main-container <?php echo $barColor; ?>">
<div class="txt"><?php echo $opt; ?></div>
<div class="wrap">
<div class="bar-percentage"><?php echo $votePercent; ?></div>
<div class="bar-container">
<div class="bar" style="width: <?php echo $votePercent; ?>;"></div>
</div>
</div>
</div>
<?php $i++; } } ?>
<a href="index.php">Back To Poll</a>

Код CSS

В файле index.php используется следующий CSS-код для определения стилей темы и параметров опроса скрипта HTML на голосование:

.pollContent{
float: left;
width: 500px;
}
.pollContent h3 {
font-size: 18px;
color: #333;
text-align: left;
float: left;
border-bottom: 2px solid #333;
width: 100%;
margin: 0 auto;
padding-bottom: 10px;
}
.pollContent ul{
list-style: none;
float: left;
width: 100%;
padding: 10px;
}
.pollContent input[type="submit"], .pollContent a{
border: none;
font-size: 16px;
color: #fff;
border-radius: 3px;
padding: 10px 15px 10px 15px;
background-color: #34a853;
text-decoration: none;
cursor: pointer;
}

В файле results.php используется следующий CSS-код для определения стилей результатов опроса с помощью скрипта социального голосования:

#container { text-align: center; margin: 20px; }
h2 { color: #CCC; }
a { text-decoration: none; color: #EC5C93; }
.bar-main-container {
margin: 10px auto;
width: 300px;
height: 55px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
font-family: sans-serif;
font-weight: normal;
font-size: 0.8em;
color: #FFF;
}
.wrap { padding: 8px; }
.bar-percentage {
float: left;
background: rgba(0,0,0,0.13);
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
padding: 9px 0px;
width: 18%;
height: 16px;
margin-top: -15px;
}
.bar-container {
float: right;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
height: 10px;
background: rgba(0,0,0,0.13);
width: 78%;
margin: 0px 0px;
overflow: hidden;
}
.bar-main-container .txt{
padding-top: 5px;
font-size: 16px;
font-weight: bold;
}
.bar {
float: left;
background: #FFF;
height: 100%;
-webkit-border-radius: 10px 0px 0px 10px;
-moz-border-radius: 10px 0px 0px 10px;
border-radius: 10px 0px 0px 10px;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
filter: alpha(opacity=100);
-moz-opacity: 1;
-khtml-opacity: 1;
opacity: 1;
}
/* ЦВЕТА */
.azure { background: #38B1CC; }
.emerald { background: #2CB299; }
.violet { background: #8E5D9F; }
.yellow { background: #EFC32F; }
.red { background: #E44C41; }

Заключение

В этой статье мы описали процесс создания простого скрипта для голосования HTML с помощью PHP и MySQL. Вы можете легко расширить этот простой скрипт. Это руководство призвано лишь помочь понять принцип создания модулей для голосования и разработать собственный вариант реализации.

Перевод статьи «Online Poll and Voting System with PHP and MySQL» дружной командой проекта Сайтостроение от А до Я.

О нас seoexpert

продвижение сайта,seo оптимизация,поисковое продвижение,раскрутка сайтов,поисковая оптимизация,продвижение сайта в гугл,seo раскрутка,продвижение сайтов в яндексе,продвижение сайта в google,продвижение сайтов в топ 10,Оптимизация и продвижение сайтов,услуги продвижения сайта,заказать продвижение,продвижение сайтов в топ,сео раскрутка сайта

Смотрите также

10 лучших IDE

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