Приветствую
Возникло желание разместить на сайте небольшую голосовалку. Возможно, ли это реализовать на простом html сайте (без использования движка)? Если да, то как?
Если статья понравилась, то поделитесь ей в социальных сетях:
Комментарии:
10
Константин
02.02.2021, 17:38
Приветствую, спасибо за скрипт. единственный вопрос с накруткой голосов, COOKIE не очень хорошо работают, может возможно добавить защиту по IP?
Daler
03.01.2018, 03:44
Добрый день. Переменная $current — отвечает за то какой pool — опрос отображается. Не подскажите как сделать переключатель ввиде далее между опросами? И как добавить больше вопросов и ответов в 1 опрос, буду очень признателен
Александр Мальцев
12.04.2017, 04:25
Как можно создать опросы на сайте, которые сохраняют данные не в базу, а в обычный текстовый файл...
Данная инструкция пригодиться не только тем, у кого нет CMS, но и тем, у кого она есть. Кроме этого данный вариант может также пригодиться тем, у кого имеются высоконагруженные сайты, т.к. предложенная голосовалка для сайта практически не будет создавать нагрузку на процессор, а базу данных она вообще не использует. Работать созданная система опроса на сайте будет через AJAX и использовать COOKIE (для защиты от накрутки).
Скриншоты, т.е. как будет выглядеть блока опроса и его результаты на сайте:
Формат хранения результатов на сервере (JSON):
{"pool-1":[3,2,5,2],"pool-2":[0,2,3,1,0]}
Как подключить голосовалку к страницам сайта:
1. Вставить в необходимую часть страницы следующий HTML-код голосовалки (оформление формы выполнено с помощью стилей Bootstrap):
Внимание: В HTML коде необходимо указать путь к файлу poll-vote.php (если конечно он не находится в той же директории, в которой расположена и страница).
Если на сайте не используется Bootstrap, то тогда необходимо написать стили для оформления опроса и результатов голосования.
2. Вставить следующий фрагмент сценария JavaScript на страницу (после подключения jQuery):
<script>
$(function(){
var pathToPolls = 'polls.php';
var vote = {};
$.get(pathToPolls, function(data) {
var data = JSON.parse(data);
vote['id']=data['id'];
vote['question']=data['question'];
vote['answers']=data['answers'];
if (data.hasOwnProperty('result')) {
$('#vote').parent().parent().find('.question').text(vote['question']);
var _answers = vote['answers'];
var output = '';
var result = data['result'];
var totalvotes = 0;
for (var i=0; i <= result.length-1; i++) {
totalvotes += result[i];
}
for (var i=0; i <= result.length-1; i++) {
output += '<p style="margin:0px;">'+_answers[i]+'</p>'+
'<p class="text-right" style="margin:0px;"><b>'+((result[i]/totalvotes)*100).toFixed(1)+'%</b> (Голосов: '+result[i]+')</p>'+
'<div class="progress">'+
'<div class="progress-bar progress-bar-info progress-bar-striped" role="progressbar" aria-valuenow="'+(result[i]/totalvotes)*100+'" aria-valuemin="0" aria-valuemax="100" style="width: '+(result[i]/totalvotes)*100+'%">'+
'<span class="sr-only">'+(result[i]/totalvotes)*100+'%</span>'+
'</div>'+
'</div>';
}
$('#vote-section').html(output);
} else {
processPoll();
}
});
var processPoll = function() {
var _id = vote['id'];
var _answers = vote['answers'];
var form = $('#vote');
form.parent().parent().find('.question').text(vote['question']);
form.prepend('<input type="hidden" name="count" value="'+vote['answers'].length+'">');
form.prepend('<input type="hidden" name="id" value="'+vote['id']+'">');
var answers = form.find('.answers');
for (var i=0; i<=vote['answers'].length-1;i++) {
answers.append('<div class="radio">'+
'<label>'+
'<input type="radio" name="poll" value="'+(i+1)+'">'+
vote['answers'][i]+
'</label>'+
'</div>');
}
if (form.find('button[type="submit"]:disabled')) {
form.find('input[type="radio"]').click(function(){
form.find('button[type="submit"]').prop('disabled',false);
form.find('input[type="radio"]').off('click');
});
};
form.submit(function(e) {
//отмена действия по умолчанию для кнопки submit
e.preventDefault();
$.post(form.attr('action'), form.serializeArray(), function(data) {
if (data) {
var data = JSON.parse(data);
var output = '';
var result = data[_id];
var totalvotes = 0;
for (var i=0; i <= result.length-1; i++) {
totalvotes += result[i];
}
for (var i=0; i <= result.length-1; i++) {
output += '<p style="margin:0px;">'+_answers[i]+'</p>'+
'<p class="text-right" style="margin:0px;"><b>'+((result[i]/totalvotes)*100).toFixed(1)+'%</b> (Голосов: '+result[i]+')</p>'+
'<div class="progress">'+
'<div class="progress-bar progress-bar-info progress-bar-striped" role="progressbar" aria-valuenow="'+(result[i]/totalvotes)*100+'" aria-valuemin="0" aria-valuemax="100" style="width: '+(result[i]/totalvotes)*100+'%">'+
'<span class="sr-only">'+(result[i]/totalvotes)*100+'%</span>'+
'</div>'+
'</div>';
}
$('#vote-section').html(output);
}
});
});
};
});
</script>
В переменной pathToPolls указать путь к файлу polls.php.
3. На сервере…
На сервере используются 2 файла php (polls.php и poll-vote.php).
В файле polls.php хранятся все опросы в формате ассоциативного массива (каждый опрос – это объект).
Синтаксис опроса:
Для того чтобы добавить новый опрос, необходимо продублировать этот код и ввести необходимые значения в соответствующие переменные.
Установка, какой опрос показывать на страницах управляется с помощью значения переменной $current.
$current = 'pool-1';
Это очень удобно, т.к. ничего не надо править на страницах. Т.е. для того чтобы установить показ другого опроса на всех страницах сайта достаточно будет просто указать необходимый ключ опроса в качестве значения этой переменной.
Также этот файл возвращает результаты, если пользователь уже проголосовал на сайте (для этого используются COOKIE).
Второй файл (poll-vote.php) записывает данные голосования в файл poll-results.txt, который создаётся по умолчанию в той же директории, в которой расположены эти 2 php файла. В качестве формата данных используется ассоциативный массив. Кроме этого данный файл после того как пользователь проголосовал ещё возвращает результаты голосования (в качестве ответа).
Код файла polls.php:
<?php
$nameFile = 'poll-results.txt';
$current = 'pool-2';
$votes = array();
// pool-1
$key = 'pool-1';
$value = new stdClass();
$value->id = $key;
$value->question = 'Какая стихия вам ближе?';
$value->answers = array('Огонь','Воздух','Вода','Земля');
$votes[$key]=$value;
// pool-2
$key = 'pool-2';
$value = new stdClass();
$value->id = $key;
$value->question = 'Какой ваш любимый цвет?';
$value->answers = array('Красный','Оранжевый','Зелёный','Синий','Нет, другой');
$votes[$key]=$value;
/* блок для вывода результатов если пользователь проголосовал */
if (isset($_COOKIE['polls'])) {
$arrayPolls = explode(',',$_COOKIE['polls']);
if (in_array($current, $arrayPolls)) {
// получаем содержимое файла
$output = file_get_contents(dirname(__FILE__).'/'.$nameFile);
// декодируем содержимое в массив
$output = json_decode($output, true);
// проверяем есть если указанный ключ голосования в ассоциативном массиве
if (array_key_exists($current, $output)) {
// получаем значение, связанное с указанным ключом
$votes[$current]->result = $output[$current];
}
}
}
echo json_encode($votes[$current]);
exit();
Код файла poll-vote.php:
<?php
// Если запрос не AJAX (XMLHttpRequest), то завершить работу
if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {return;}
if (empty($_POST['id'])) {exit();}
$nameFile = 'poll-results.txt';
$id = $_POST['id'];
$answer = $_POST['poll'];
$count = $_POST['count'];
if (isset($_COOKIE['polls'])) {
$arrayPolls = explode(',',$_COOKIE['polls']);
if (in_array($id, $arrayPolls)) {
exit();
}
}
// массив, который будем возвращать клиенту
$result = array();
// если файлами с результатами нет
if (!file_exists($nameFile)) {
// результирующий массив
$output = array();
// массив для хранения ответов
$answers = array();
// заполняем массив нулями
for ($i=0; $i<=$count-1; $i++) {
$answers[$i] = 0;
}
// увеличиваем в массиве полученный элемент на 1
$answers[$answer-1] = $answers[$answer-1] + 1;
// связываем id опроса с ответами
$output[$id] = $answers;
// кодируем ассоциативный массив в JSON
$output = json_encode($output);
// записываем в файл
file_put_contents(dirname(__FILE__).'/'.$nameFile, $output, LOCK_EX);
} else {
// получаем содержимое файла
$output = file_get_contents(dirname(__FILE__).'/'.$nameFile);
// декодируем содержимое в массив
$output = json_decode($output, true);
// проверяем есть если указанный ключ голосования в ассоциативном массиве
if (array_key_exists($id, $output)) {
// получаем значение, связанное с указанным ключом
$answers = $output[$id];
// увеличиваем в массиве полученный элемент на 1
$answers[$answer-1] = $answers[$answer-1] + 1;
// перезеписываем массив ответов, связанных с ключом
$output[$id] = $answers;
} else {
/* если не найден переданный ключ в массиве */
// массив для хранения ответов
$answers = array();
// заполняем массив нулями
for ($i=0; $i<=$count-1; $i++) {
$answers[$i] = 0;
}
// увеличиваем в массиве полученный элемент на 1
$answers[$answer-1] = $answers[$answer-1] + 1;
// добавляем в результирующий массив ключом и связанный с ним ассоциативный массив
$output[$id] = $answers;
}
// кодируем ассоциативный массив в JSON
$output = json_encode($output);
// записываем в файл
file_put_contents(dirname(__FILE__).'/'.$nameFile, $output, LOCK_EX);
}
if (isset($_COOKIE['polls'])) {
$arrayPolls = explode(',',$_COOKIE['polls']);
} else {
$arrayPolls = array();
}
array_push($arrayPolls,$id);
setcookie('polls', implode(',',$arrayPolls),time() + (86400 * 365),'/');
$result[$id] = $answers;
$result = json_encode($result);
echo $result;
exit();
?>
Александр спасибо, отличный вариант. Обязательно попробую в действии.
Иван Шеин
28.07.2021, 19:21
Здравствуйте. Такой вопрос — можно ли сделать так, чтобы, помимо того, чтобы записывалось в текстовый файл, ещё скидывался результат на указанную почту? Ну или вместо файла результаты на почту.
Я предполагаю, что для этого надо в php файле poll-vote.php изменить или добавить параметры для отправки на почту.
Но к сожалению знаний мне для этого ещё не достаточно. Подскажите, мои рассуждения верны? И, если верны, прошу подсказать, что и куда вписать)
Иван Шеин
28.07.2021, 19:25
А так же вопрос касаемо тайминга. Т.е. мне надо, чтобы опросы сбрасывались во вторник после 20:00, в четверг после 20:00 и в субботу. Так же после 20:00.
Если это, конечно, возможно.
Александр Мальцев
04.08.2021, 04:53
Привет! Чтобы это реализовать, лучше создать новый php-файл, который будет брать данные из «poll-results.txt», формировать нужное тело письма и отправлять его адресатам. Запускать этот файл можно через планировщика cron (обычно имеется на всех виртуальных хостингах), указав в нём нужные дни и нужное время.
Иван Шеин
04.08.2021, 06:38
А подскажете, как это сделать? А то я недавно в программировании. Освоил пока HTML, по нужде залез в CSS, но Java и php для меня пока тёмный лес(
Александр Мальцев
10.04.2017, 15:39
Здравствуйте! Простую голосовалку можно реализовать и без движка. Но всё равно потребуется написать серверный скрипт и выбрать хранилище, в котором сохранять данные голосования (как минимум текстовый файл).
Андрей
10.04.2017, 15:45
Приветствую Александр. Я как раз и думал о простом текстовом файле для сохранения данных голосования. Подскажите, по скрипту есть какие-то шаблоны? Где можно узнать поподробнее?
Данная инструкция пригодиться не только тем, у кого нет CMS, но и тем, у кого она есть. Кроме этого данный вариант может также пригодиться тем, у кого имеются высоконагруженные сайты, т.к. предложенная голосовалка для сайта практически не будет создавать нагрузку на процессор, а базу данных она вообще не использует.
Работать созданная система опроса на сайте будет через AJAX и использовать COOKIE (для защиты от накрутки).
Скриншоты, т.е. как будет выглядеть блока опроса и его результаты на сайте:
Формат хранения результатов на сервере (JSON):
Как подключить голосовалку к страницам сайта:
1. Вставить в необходимую часть страницы следующий HTML-код голосовалки (оформление формы выполнено с помощью стилей Bootstrap):
Внимание: В HTML коде необходимо указать путь к файлу poll-vote.php (если конечно он не находится в той же директории, в которой расположена и страница).
Если на сайте не используется Bootstrap, то тогда необходимо написать стили для оформления опроса и результатов голосования.
2. Вставить следующий фрагмент сценария JavaScript на страницу (после подключения jQuery):
В переменной pathToPolls указать путь к файлу polls.php.
3. На сервере…
На сервере используются 2 файла php (polls.php и poll-vote.php).
В файле polls.php хранятся все опросы в формате ассоциативного массива (каждый опрос – это объект).
Синтаксис опроса:
Для того чтобы добавить новый опрос, необходимо продублировать этот код и ввести необходимые значения в соответствующие переменные.
Установка, какой опрос показывать на страницах управляется с помощью значения переменной $current.
Это очень удобно, т.к. ничего не надо править на страницах. Т.е. для того чтобы установить показ другого опроса на всех страницах сайта достаточно будет просто указать необходимый ключ опроса в качестве значения этой переменной.
Также этот файл возвращает результаты, если пользователь уже проголосовал на сайте (для этого используются COOKIE).
Второй файл (poll-vote.php) записывает данные голосования в файл poll-results.txt, который создаётся по умолчанию в той же директории, в которой расположены эти 2 php файла. В качестве формата данных используется ассоциативный массив. Кроме этого данный файл после того как пользователь проголосовал ещё возвращает результаты голосования (в качестве ответа).
Код файла polls.php:
Код файла poll-vote.php:
Скачать готовый пример можно с Яндекс Диска.
Проект на Githib: github.com/itchief/simple-poll
Я предполагаю, что для этого надо в php файле poll-vote.php изменить или добавить параметры для отправки на почту.
Но к сожалению знаний мне для этого ещё не достаточно. Подскажите, мои рассуждения верны? И, если верны, прошу подсказать, что и куда вписать)
Если это, конечно, возможно.