Хочу рассказать Вам, как написать голосование на PHP. Голосование - хорошее средство для того, что бы узнать мнение посетителей сайта, по какому либо вопросу. Хорошо продуманное голосование может помочь понять веб мастеру, что не так на его сайте, что нужно изменить, что добавить и т.д. Но, не буду Вас учить, как выбирать тему для голосования.
Лучше подскажу, как написать удобную систему голосований. Переходим к делу. Несколько слов, о том, каким будет скрипт, и как он должен работать. С помощью скрипта можно будет создавать неограниченное количество голосований. Скрипт будет называться vote.php, а файл, в котором хранится инфа по голосованиям - vote.dat. Скрипт состоит из админской части, части,
которая отображает голосование, и которая учитывает голоса. Чтобы получить доступ к любой из этих частей, будем использовать параметр-переменную action. Мы будем передавать эту переменную скрипту с помощью командной строки браузера. В зависимости, от того, какое значение примет action, скрипт будет выполнять определённые действия. Теперь о структуре файла vote.dat. Каждая строка это отдельное голосование. Строка выглядит следующим образом: Вопрос голосования~Вариант ответа №1|количество проголосовавших за этот вариант~Вариант ответа №2|количество проголосовавших за этот вариант~...и т.д....~Вариант ответа №n|количество проголосовавших за этот вариант."|" и "~"(тильда) - служат разделителями (separator). Для чего эти разделители нужны, смотрите ниже. Далее привожу исходник скрипта с подробными комментариями.
<?php
$datfile="vote.dat"; //файл - база голосований
$pas="pas";//пароль для доступа в админскую часть
$data=file($datfile);
$nomofvote=count($data); //Считываем файл в список $data, и считаем количество голосований
if(!isset($action))
Если, по какой-то причине, скрипту не передаётся переменная $action, выводим список всех голосований. Функция isset(mixed var) равна true, если переменная существует.
{
$data=array_reverse($data);
echo ("
Список всех голосований:<br>
");
for($i=0;$i<$nomofvote;$i++)
{
$temp=explode("~",$data[$i],2);
Переворачиваем список (функция array_reverse(array array)). Это сделано для того, чтобы первым выводилось голосование, которое было добавлено последним. Помните, в начале, я говорил о разделителях - "~" и "|"? Тут они нам и понадобятся. Функция explode(string separator, string string[, int limit) разбивает строку, переданную ей вторым параметром, по разделителю (первый параметр). Части "разрезанной" строки помещаются в массив-список, который эта функция и возвращает. Если задан необязательный параметр $limit, то возвращаются только первые ($limit-1) участков "разреза". Запомните, что в качестве разделителей, во избежании ошибки (неправильного разделения строки), используют редко употребляемые символы. Например:"|","~","::","*"и т.д. Т.к. мы выводим список всех голосований (только их названия), то нам нужны только первые
элементы всех строк массива $data (см. структуру файла). Проходимся по всем голосованиям с помощью цикла.
echo
("
<p><a href=$PHP_SELF?action=view&id=$i>$temp[0]</a></p>
");
}
}
Вывод названия голосования делаем в виде ссылки, нажав на которую, можно будет проголосовать. Напоминаю, что переменная $PHP_SELF - содержит в себе URL текущей страницы. Можно было написать и так:
<a href=vote.php?action=view&id=$i>$temp[0]</a>. Ошибки не будет, но, если Вы захотите переименовать файл скрипта, Вам придётся изменять это название и в коде скрипта. Поэтому лучше использовать $PHP_SELF.
elseif ($action=="admin")
{
Если $action=="admin", то входим в админскую часть.
if($pas==@$password)
{
Проверяем пароль. Так как переменная $password, может быть не инициализирована (не определена), то отключаем сообщение об ошибках
@$password.
echo("<a href=$PHP_SELF?action=add&password=$pas>Добавить голосование</a><br>");
for($i=0;$i<$nomofvote;$i++)
{ $temp=explode("~",$data[$i]);
echo("<br>$temp[0] <a href=$PHP_SELF?action=delete&id=$i&password=$pas>Удалить</a><br>");
}
}
else
{
Если пароль правильный, то выводим ссылку для добавления голосования и список всех голосований со ссылками на удаления. При удалении голосования передаём скрипту $action=delete, номер удаляемого голосования и пароль.
echo("Забыли ввести пароль?
<form action=$PHP_SELF?action=admin method=post><input type=text
name=password><input type=submit name=button1 value=Submit></form>");
}
}
Если пароль не верный или не был передан скрипту, то отображаем форму для ввода пароля
elseif($action=="delete" & @$password==$pas)
{
for($i=0;$i<$nomofvote;$i++) $data[$i]=chop($data[$i]);
unset($data[$id]);
$data=implode("\n",$data);
/*Записываем всё в файл.*/
$f=fopen($datfile,"w");
fwrite($f,$data);
fclose($f);
echo
/*Ссылочка для возврата к администрированию.*/
("
Голосование удалено из базы $datfile<br>
<a href=$PHP_SELF?action=admin&password=$pas>Вернуться к администрированию</a>
");
}
Проверяем, если $action=="delete" и $password==$pas, то обрезаем лишние концевые пробелы. Это делает функция chop(string str). Удаляем то голосование (т.е. строку списка $data), номер которого ($id) был передан
нам из админской части. Любую переменную, или элемент массива можно удалить с помощью функции - unset(mixed var). C помощью функции implode(string glue, array pieces) - "склеиваем" все элементы массива $data в одну строку, для того чтобы записать её в файл vote.dat. Функция implode() - "склеивает" элементы массива по "строке-клею". В общем, эта функция делает обратное действие к функции explode().
elseif($action=="add" & @$password==$pas)
Раздел для добавления нового голосования.
{
if(!isset($newvotebut))
/*Проверяем, не нажата ли кнопка $newvotebut. Если это так, выводим форму для добавления нового голосования.*/
{
echo("
<form action=$PHP_SELF?action=add&password=$pas method=post>тема голосования:
<input type=text name=tema value=Вопрос голосования> <br>
Варианты ответов (до 5 штук):<br>
<input type=text name=otv[]><br>
<input type=text name=otv[]><br>
<input type=text name=otv[]><br>
<input type=text name=otv[]><br>
<input type=text name=otv[]><br>
<br>
<input type=submit name=newvotebut value=Добавить></form>");
}
Обратите внимание на то, как заданы имена полей формы (name=otv[]). В результате РНР создаст список, значениями которого будут значения полей формы. Если вам нужно больше полей для вариантов ответа, просто добавьте ещё несколько строк <input type=text name=otv[]>.
else
Если кнопка $newvotebut была нажата, то осуществляем добавление нового голосования в базу. Нам нужно сформировать строку $newvote, в соответствии с условиями файла vote.dat, о структуре которого сказано выше.
{
$newvote=$tema;
/*Тема голосования не требует изменений, так что сразу записываем её в $newvote */
for ($i=0;$i<count($otv);$i++)
if($otv[$i]!==""){
$newvote=$newvote."~".$otv[$i]."Ә";}
Проверяем все поля вариантов ответов. Если поле не пустое, то добавляем к строке $newvote разделитель - "~", сам вариант ответа - $otv[$i], и начальное значение количества голосов за этот вариант с разделителем -
"Ә". Объединять строки нужно точкой, т.к. именно этот символ служит для конкатенации строк в PHP.
$newvote=$newvote."\n";
Ко всему этому добавляем символ перевода строки - "\n". Если тестируете скрипт под Windows, замените во всём скрипте "\n"
на "\r\n". Кто не понимает зачем, прочтите мою статью "Работа с файлами".
$f=fopen($datfile,"a");
fwrite($f,$newvote);
fclose($f);
/*Записываем всё в файл. Файл открываем с параметром "а", т.е. данные будут дописаны в конец файла.*/
echo
("
Голосование добавлено в базу $datfile<br>
<a href=$PHP_SELF?action=admin&password=$pas>Вернуться к администрированию</a>
");
}
}
elseif($action=="view")
Продолжаем проверять наш параметр action. Если $action=="view", то отображаем голосование под номером $id.
{
if(!isset($id)) $id=0;
Если $id не задан - можно отобразить любое голосование. В данном случае это самое первое голосование в файле vote.dat. Теперь Вы можете вывести ссылку на любое из Ваших голосований. Она будет иметь следующий вид: <a href=vote.php?action=view&id=номер голосования, которое нужно вывести>Смотреть голосование ...</a>.
if ($id>$nomofvote || $id<0) echo("Такого голосования не существует, смените id");
Проверяем, правильно ли указан $id.
else
{
$content=explode("~",$data[$id]);
echo("$content[0] <form action=$PHP_SELF?action=vote&id=$id method=post>");
Если всё правильно, то выводим тему голосования.
for($i=1;$i<count($content);$i++)
{
$temp=explode("|",$content[$i]);
echo("$temp[0]
Количество голосов: $temp[1]<br>Проголосовать<input name=name value=$i type=radio><br>");
}
echo("<input name=vote type=submit value=голосовать>");
}
}
Выводим варианты ответов, зависимые переключатели (radio) и кнопку vote. Каждый переключатель имеет своё значение. Первый - 1, второй - 2 и т.д. Переменная $name будет принимать различные значения в зависимости от того, за что отдаст свой голос посетитель.
elseif(isset($vote)){
Проверяем, была ли нажата кнопка из предыдущей формы - vote.
/*Если да, то добираемся к нужному нам варианту ответа/
$content=explode("~",$data[$id]);
$temp=explode("|",$content[$name]);
/*Увеличиваем количество голосовавших на 1 */
$temp[1]=$temp[1]+1;
$content[$name]=$temp[0]."|".$temp[1];
$data[$id]=implode("~",$content);
for($k=0;$k<$nomofvote;$k++) $data[$k]=chop($data[$k]);
$data=implode("\n",$data);
$f=fopen($datfile,"w");fwrite($f,$data);
fclose($f);
/*Записываем все изменение в файл*/
echo
("
Спасибо за Ваш Голос
<a href=$PHP_SELF?action=view>Назад</a>
");
}
else
{
$nomofvote--;
echo
("
Неправильно задан параметр action <br><a href=$PHP_SELF?action=admin>Администрировать</a>
<br><a href=$PHP_SELF?action=view&id=$nomofvote>Смотреть последнее голосование</a><br>
<a href=$PHP_SELF>Смотреть весь список голосований</a>
");
}
?>
Если не одно из условий не выполняется, то выводим три ссылки: "Администрировать", "Смотреть последнее голосование",
"Смотреть весь список голосований".
Конечно, этот скрипт далёк от идеальной системы голосований. Нет некоторых проверок на правильность, защиты от накруток и т.д. Но к использованию он годится. Возможно, скоро я
расскажу, как его усовершенствовать.