Консультация № 50256
26.07.2006, 16:13
0.00 руб.
0 2 2
Уважаемые эксперты!

Имеется код скрипта для голосования (в Приложении). Небходимо защитить этот скрипт от возможности повторного голосования посредством IP-пользователя. Не могли бы вы мне сказать, как это сделать? Предложите ваш вариант полного скрипта или модифицируйте этот (желательно).

Мне бы также хотелось знать, насколько этот скрипт идеален и, самое главное, безопасен.

Надеюсь на Вашу помощь.
Спасибо!

Приложение:
<h3 class="headercolor"> Результаты online-опроса на тему:
" <?php $strings = file("voting/browser.txt"); ?> <? echo $strings[0]; ?>"</h3></td> </tr> <tr> <td height="21" valign="top"> <?php$file_q = "voting/browser.txt";$file_r = "voting/ansbrow.txt";$image_1x1 = "voting/bar.gif";$results = file($file_r);$outer = "";for ($i=0; $i<count($results); $i++){ $results[$i] = (int) $results[$i]; if ($i == ($variant-1)) $results[$i]++; $outer = $outer.$results[$i]."\n";}$fp = fopen($file_r, "w"); if ($fp) { $counter=fputs($fp,$outer); fclose($fp); } else { echo "Произошла ошибка записи результатов!"; }show_results();function show_results() {global $file_q, $file_r, $image_1x1;$strings = file($file_q);$results = file($file_r);$total = 0;echo "
<img src=‘", $image_1x1, "‘ height=1 width=100% style=‘background-color: gray‘>
";for ($i=0; $i<count($results); $i++){ $results[$i] = (int) $results[$i]; $total += $results[$i];}echo "<table width=100% cellspacing=0 cellpadding=0>";for ($i=0; $i<count($results); $i++){ $percentage = round($results[$i]/$total*100); echo "<tr><td width=50%><table align=right cellspacing=0 cellpadding=0 width=", $percentage, "% bgcolor=gray><tr><td><img src=‘image/11.gif‘ width=0 height=10></table><td width=5% align=right>", $percentage, "% <td width=5% align=center>", $results[$i], "<td width=40%>", $strings[$i+1];}echo "<tr><td colspan=4><img src=‘", $image_1x1, "‘ height=1 width=100% style=‘background-color: gray‘><tr><td align=right colspan=2>Всего ", form_vot($total), "<td align=center>", $total, "<td>", form_man($total);echo "</table>";}function form_man($need) { $man = array("баллов", // [0] "баллов", // [1] "баллов", // [2] "баллов", // [3] "баллов", // [4] "баллов", // [5] "баллов", // [6] "баллов", // [7] "баллов", // [8] "баллов"); // [9]$need = substr((string) $need, -1);if ((int) substr((string) $need, -2, 1) != 1) { return $man[(int)$need];} else { return "баллов";} }function form_vot($need) {if ((int) substr((string) $need, -2, 1) != 1) {if ((int) substr((string) $need, -1) != 1) return "набрано:"; else return "набрано:";} else {return "набрано:";}}?>

Обсуждение

Неизвестный
26.07.2006, 16:33
общий
это ответ
Здравствуйте, Демьянчук Виталий!

Сохраняй IP проголосовавших, например в voting/ip.txt. И при кадом голосовании проверяй, есть ли IP в списке проголосовавших, если есть - выводи "Вы уже проголосовали!".
Примерно так:

Приложение:
$ip=getenv(‘REMOTE_ADDR‘);$file_ip=‘voting/ip.txt‘;$iplist=file($file_ip);if(array_search($ip,$iplist)!==FALSE){ echo "Вы уже проголосовали!!!"; exit;}$iplist[]=$ip;file_put_contents($file_ip,implode("\n",$iplist));
Неизвестный
26.07.2006, 16:43
общий
это ответ
Здравствуйте, Демьянчук Виталий!
Сразу скажу следующее: посредством проверки IP адреса пользователя Вы этот скрипт от повторного голосования никак не защитите. Дело в том что у большинства пользователей коммутируемый доступ в интернет, а следовательно у них динамические IP.
Как вариант могу предложить реализацию системы голосований, описание которой прилагаю. (см. ниже)
Пользователь регистрируется (логин и пароль), и голосует. Голосований может быть несколько, все они разбиты по категориям. Пользователю запрещено менять логин. Таким образом совершенно исключена возможность повторного голоса одного и того же пользователя (при ответе просто проверять, голосовал ли этот пользователь или нет).
Если такой вариант не устраивает, предлагаю альтернативу с cookies. Т.е. запоминать все данные у клиента. Но здесь тоже есть проблема, а именно: если пользователь отключит cookies, Ваш скрипт будет работать некорректно.

Теперь по поводу самого скрипта. Рекомендую использовать функцию <b>flock</b> при записи в файл. Описание функции Вы можете прочитать <a href=‘http://ru.php.net/manual/ru/function.flock.php‘>здесь</a>.
Ещё одно замечание по поводу идеальности скрипта. Вы выводите html-данные посредством <b>echo</b>. Дело в том что <b>echo</b> относится к php, как следствие тратятся лишние ресурсы. Это не принципиально (у каждого свой стиль программирования), но, всё-таки, лучше выводить html-данные (формы, таблицы и т.д) не прибегая к php.
С учётом всего сказанного привожу изменённый код (см. приложение).

Надеюсь что помог Вам своим ответом.

Удачи!
С уважением,

Марк.

Приложение:
<h3 class="headercolor"> Результаты online-опроса на тему:
" <?php $strings = file("voting/browser.txt"); ?> <? echo $strings[0]; ?>"</h3></td> </tr> <tr> <td height="21" valign="top"> <?php$file_q = "voting/browser.txt";$file_r = "voting/ansbrow.txt";$image_1x1 = "voting/bar.gif";$results = file($file_r);$outer = "";for ($i=0; $i<count($results); $i++){ $results[$i] = (int) $results[$i]; if ($i == ($variant-1)) $results[$i]++; $outer = $outer.$results[$i]."\n";}$fp = fopen($file_r, "w"); if ($fp) { flock($fp, LOCK_EX); $counter=fputs($fp,$outer); fclose($fp); flock($fp, LOCK_UN); fclose($fp); } else { ?> <p>Произошла ошибка записи результатов!</p> <?php }show_results();function show_results() {global $file_q, $file_r, $image_1x1;$strings = file($file_q);$results = file($file_r);$total = 0;?>
<img src=<?php echo $image_1x1 ?> height=1 width=100% style=‘background-color: gray‘>
<?phpfor ($i=0; $i<count($results); $i++){ $results[$i] = (int) $results[$i]; $total += $results[$i];}?><table width=100% cellspacing=0 cellpadding=0><?phpfor ($i=0; $i<count($results); $i++){ $percentage = round($results[$i]/$total*100); ?> <tr><td width=50%><table align=right cellspacing=0 cellpadding=0 width=<?php echo $percentage ?>% bgcolor=gray><tr><td><img src=‘image/11.gif‘ width=0 height=10></table><td width=5% align=right><?php echo $percentage ?>%<td width=5% align=center><?php echo $results[$i] ?><td width=40%><?php echo $strings[$i+1];}?><tr><td colspan=4><img src=‘", $image_1x1, "‘ height=1 width=100% style=‘background-color: gray‘><tr><td align=right colspan=2>Всего <?php form_vot($total) ?> <td align=center><?php echo $total ?><td><?php form_man($total); ?></table><?php}function form_man($need) { $man = array("баллов", // [0] "баллов", // [1] "баллов", // [2] "баллов", // [3] "баллов", // [4] "баллов", // [5] "баллов", // [6] "баллов", // [7] "баллов", // [8] "баллов"); // [9]$need = substr((string) $need, -1);if ((int) substr((string) $need, -2, 1) != 1) { return $man[(int)$need];} else { return "баллов";}}function form_vot($need) {if ((int) substr((string) $need, -2, 1) != 1) {if ((int) substr((string) $need, -1) != 1) return "набрано:"; else return "набрано:";} else {return "набрано:";}}?>
Форма ответа