Скрипт голосования на PHP
Уже несколько раз посетители нашего сайта обращались к нам через форму обратной связи и по внутренней почте форума с просьбой сделать PHP скрипт для голосования посетителей на сайте. Пожелания по функциональности были самые разнообразные. Проанализировав несколько популярных скриптов, имеющихся в сети, мы пришли к выводу, что у них имеются разнообразные недостатки. В связи с этим было принято решение о создании своего собственного скрипта для голосования на PHP.
Пример работы предлагаемого нами скрипта голосования на PHP расположен ниже:
Самым простым решением было бы использование MySQL, но не у всех наших посетителей он имеется на хостинге, либо у некоторых хостеров доступен за дополнительную плату.
Самым важным моментом при создании своего собственного скрипта для голосования, как нам кажется, является то, что скриптом должен учитываться только один голос с одного IP адреса для каждого голосования. Следующим важным моментом является защита файла результатов от записи в момент, пока с файлом работает другой процесс (особенно актуально для сайтов с высокой посещаемостью). Это необходимо для предотвращения потери данных. Подробнее можно ознакомиться в другой нашей теме - Блокировка файлов от записи на PHP.
Также скриптом должна производиться проверка всех полученных данных, для исключения неправильного подсчета голосов. Сделано это должно быть для защиты от недобросовестных посетителей, которые могут отправить в форме нереальные значения варианта голосования.
Далее приводим полный PHP код для реализации голосования на своем сайте, который получился у нас после добавления в него необходимых функций:
<?php
$file='';
$file_ip='';
$message='<br>';
$view_res=0;
if (isset($_POST['view_res']) and is_numeric($_POST['id'])) $view_res=1;
if (isset($_POST['vote']) and is_numeric($_POST['item'])
and is_numeric($_POST['id'])) {
$f_name="vote".$_POST['id'].".txt";
$f_ip="vote".$_POST['id']."_ip.txt";
$ip=$_SERVER['REMOTE_ADDR'];
$fh_ip=fopen($f_ip,"a+");
flock($fh_ip,LOCK_EX);
fseek($fh_ip,0);
while (!feof($fh_ip)) $file_ip=fread($fh_ip,4096);
if (array_search($ip,explode(",", $file_ip))!==FALSE) {
$message="<b>Вы уже голосовали!</b><br>";
}
else if (file_exists($f_name)) {
$fh=fopen($f_name,"a+");
flock($fh,LOCK_EX);
fseek($fh,0);
while (!feof($fh)) $file=fread($fh,4096);
$file=explode(",", $file);
if ($_POST['item']>=0 and $_POST['item']<count($file)) $file[$_POST['item']]+=1;
$file=implode(",",$file);
ftruncate($fh,0);
fwrite($fh,$file);
flock($fh,LOCK_UN);
fclose($fh);
$file_ip.=$ip.',';
fwrite($fh_ip,$ip.',');
$message="<b>Ваш голос учтен!</b><br>";
}
$view_res=1;
flock($fh_ip,LOCK_UN);
fclose($fh_ip);
}
if ($view_res==1) {
$f_name="vote".$_POST['id'].".txt";
if (file_exists($f_name)) {
$fh=fopen($f_name,"a+");
flock($fh,LOCK_EX);
fseek($fh,0);
while (!feof($fh)) $file=fread($fh,4096);
flock($fh,LOCK_UN);
fclose($fh);
$file=explode(",", $file);
$summ=0;
for ($n=0; $n<count($file); $n++) $summ+=$file[$n];
if ($summ==0) $summ=1;
for ($n=0; $n<count($file); $n++) $file[$n]=' - <b>'.$file[$n].
'</b> ('.round(($file[$n]*100/$summ), 2).'%)';
}
}
echo '<form method="POST" style="margin:0 0 0 35px;">Как Вам данная тема?
<input type="hidden" name="id" value="1">';
echo '<table><tr><td><input type="radio" name="item" value="0" checked>
Отлично</td><td>'.$file[0].'</td></tr>';
echo '<tr><td><input type="radio" name="item" value="1">Нормально</td><td>'.
$file[1].'</td></tr>';
echo '<tr><td><input type="radio" name="item" value="2">Сойдет</td><td>'.
$file[2].'</td></tr>';
echo '<tr><td><input type="radio" name="item" value="3">Так себе</td><td>'.
$file[3].'</td></tr>';
echo '<tr><td><input type="radio" name="item" value="4">Ужасно</td><td>'.
$file[4].'</td></tr>';
echo '<tr><td colspan="2"><input type="submit" name="view_res" value="Результат">
<input type="submit" name="vote" value="Голосовать">';
echo '</td></tr></table>'.$message.'</form>';
?>
Обращаем Ваше внимание на то, что для работы скрипта голосования, необходимо предварительно создать файл, содержащий начальные значения для каждого из вариантов ответов. Т.е., для голосования с id=1, необходимо создать файл vote1.txt, в котором будет содержаться 0,0,0,0,0 (если предполагается, что ответов будет всего пять). Файл с IP адресами, принявшими участие в данном голосовании, будет создан автоматически (vote1_ip.txt).
На первый взгляд, предлагаемый скрипт немного больше, чем имеющиеся в сети аналогичные, но в данном скрипте, как писалось ранее, есть некоторые преимущества:
- С одного IP адреса можно отдать только один голос в каждом голосовании.
- Для каждого голосования имеется свой файл ответов и файл с IP адресами.
- Использование блокировки файлов от записи для повышения надежности.
- Возможность посмотреть результаты голосования, не проголосовав (кнопка "Результат").
- Проверка всех поступивших данных от пользователей.
Таким образом, просто добавив выше приведенный PHP код на свою страничку, и создав в корневой папке сайта файл vote1.txt, содержащий начальные значения для каждого варианта ответа, Вы получите готовый скрипт голосования.
Перед публикацией все комментарии проходят обязательную модерацию!
Если Вы хотите задать какой-либо вопрос, то сделайте это на нашем форуме.
Таким образом, Вы сможете быстрее получить ответ на интересующий Вас вопрос.
И насчёт vote1.txt я правильно понял, что в файл надо написать только "0,0,0,0,0"?
0,0,0,0,0 нужно прописывать, если у Вас будет пять вариантов ответа.
Просто когда я запускаю этот скрипт в одной папке, а файл vote1.txt находится в другой, то скрипт не работает т.е. не записывает данные в этот файл.
$f_name=$_SERVER["DOCUMENT_ROOT"]."vote".$_POST['id'].".txt";
$f_ip=$_SERVER["DOCUMENT_ROOT"]."vote".$_POST['id']."_ip.txt";
Подскажите, пожалуйста, как на одной страничке сделать несколько вопросов так, чтобы было не к каждому вопросу кнопка голосовать, а ко всем вопросам сразу?
P.S. Другие php-скрипты на сайте подключены и работают (правда, не мной подключены были, поэтому и не знаю, как правильно заставить их работать).
Код понравился!
Есть возможность доделать код, чтобы было несколько вопросов с вариантами ответов, и голосование с результатом можно было выбрать после всех отвеченных вопросов?
За ранние Благодарен!
$id_test=1;
$summ=0;
$f_name="vote".$id_test.".txt";
if (file_exists($f_name)) {
$fh=fopen($f_name,"a+");
flock($fh,LOCK_EX);
fseek($fh,0);
while (!feof($fh)) $file=fread($fh,4096);
flock($fh,LOCK_UN);
fclose($fh);
$file=explode(",", $file);
for ($n=0; $n<count($file); $n++) $summ+=$file[$n];
if ($summ==0) $summ=1;
for ($n=0; $n<count($file); $n++) $file[$n]=round(($file[$n]*100/$summ), 2).'%';
}
Где $id_test - номер теста, проценты которого требуется получить.