|
..:: System oceniania artykułów + ANTYSPAM ::.. |
|
Data artykulu: 08-11-2009 17:03
(admin), modyfikowany:
12-09-2010 19:16 (admin)
|
Odwiedzin: 860
|
|
| |
|
Tagi: mysql, php, programowanie,
|
| |
|
|
|
|
|
Cywilizacja to niekończący się ciąg potrzeb, których nie potrzebujemy. (Mark Twain)
|
|
|
W pewnym momencie życia mojej strony zapragnąłem stworzyć dla użytkowników system oceniania jakości artykułów i postów. Z założenia system miał być odporny na wszelkiego typu roboty i ataki spamerskie. Szczegółowa analiza logów przez kilka miesięcy istnienia tego systemu potwierdziła, że wszystkie bez wyjątku kliknięcia zostały wykonane przez człowieka, a nie automat. Oczywiście powyższy kod ma zastosowanie tylko i wyłącznie do mojej strony, jednak – przy chociaż podstawowym rozumieniu HTML, CSS i PHP nie uważam, aby ktokolwiek miał problemy z przerobieniem i zastosowaniem poniższego kodu do własnych potrzeb.
System składa się z dwóch plików oraz wydzielonej w bazie danych MySQL tabeli (zawiera id głosu, article id – id ocenianego artykułu, ip - adres IP oraz rate - kolumnę z oceną).
Pierwszy plik, którego fragment kodu publikuje to plik odpowiedzialny za wyświetlanie każdego z osobna artykułu.
echo "
<form method="post" action="rate.php">
<input type="text" name="nick" value="catcher" style="display: none;">
<input type="text" name="email" style="display: none;">
<input type="text" name="comment" style="display: none;">
//powyższe cztery linijki to właśnie zabezpieczenie antyspamowe. Z blizej nie znanych mi przyczyn roboty NIE igrorują zapisu w stylach i wypełniają tekstem to, czego normalny użytkownik nie zobaczy na mojej stronie www, czyli ukryte pola o nazwach email, comment czy nick. Zmiana domyślnych wartości tych pól powoduje uznanie przez system głosu jako fake.
plik_glowny.php
<input type="hidden" name="article_id" value="" . $get['id'] . "">
//powyższa linijka wysyła dane na temat id ocenianego artykułu
<span style="display: -moz-inline-block; display:inline-block; padding: 1px 1px 0px 1px;
height:15px; border:1px solid #d8dfea; vertical-align: middle;">";
//indywidualny styl obramowania elementów na mojej stronie, można zmodyfikować lub usunąć
### ??? liczymy, ile razy glosowano ###
$result_rate=mysql_query("SELECT article_id, rate FROM www_rates
WHERE article_id='" . $get['id'] . "'") or die (mysql_error());
$num_rates=mysql_num_rows($result_rate);
//powyższa linijka zlicza, ile zary zagłosowano na artykuł o tym numerze id
### ??? sumujemy do kupy wszystkie oceny ###
list($sum_rates)=mysql_fetch_row(mysql_query("SELECT SUM(rate) FROM www_rates
WHERE article_id='" . $get['id'] . "'"));
$average_rates=@round($sum_rates/$num_rates); # round - zaokraglenie
//srednia ocena zaokrąglona w górę = suma wszystkich ocena / ilość głosów
//Poniżej wyświetlamy w pętli 5 gwiazdek (w pętli, bo mniej kodu)
for($m=1; $m<6; $m++)
{
echo "<input type="image" name="rate" . $m . "" ";
if ($m<=$average_rates) //ta pętla uzależnia kolor wyświetlanej gwiazdki
{
echo "src="images/full_star.gif"";
}
else
{
echo "src="images/no_star.gif"";
}
echo "
title="" . $m . "" height="15">
</span>
<span style="display: -moz-inline-block; display:inline-block; padding: 1px 1px 0 5px; height:15px;
border:1px solid #d8dfea; vertical-align: middle;">";
if ($_GET['vote_err']=="yes") //jeśli ktoś już kiedyś głosował – wyświetli się komunikat o błędzie, zmienna vote_err generowana jest przez plik rate.php, o nim później.
{
echo "<span style="text-decoration: blink; color: red;">
" . $lang_rate_retrial . "!</span>"; //zmiennąlang_rate_retrial przechowóję w pliku “językowym”
}
elseif ($_GET['vote_err']=="no") //gdy odwiedzający głosuje po raz pierwszy
{
echo "
<span style="text-decoration: blink; color: red;">
" . $lang_rate_thanks . "!</span>";
}
echo " " . $num_rates . " " . $lang_rate . "</span> "; //wyświetla napis głosowano X razy, wszelkie zmienne z przedrostkiem “lang” przechowuję w osobnym pliku, możesz to jednak oczywiście zmodyfikować
}
echo "
</form>
plik rate.php
<?
include ('includes/header.php');
//nagłówek strony
if (isset($_POST[rate1_x])) {$rate="1";}
elseif (isset($_POST[rate2_x])) {$rate="2";}
elseif (isset($_POST[rate3_x])) {$rate="3";}
elseif (isset($_POST[rate4_x])) {$rate="4";}
elseif (isset($_POST[rate5_x])) {$rate="5";}
else ($rate="spamer")
//sprawdzamy który przycisk został kliknięty. Robione jest to dość dziwną metodą, gdyż IE nie interpretuje prawidłowo parametru value w input type image. Opis problemu - patrz http://forum.php.pl/lofiversion/index.php/t66059.html. Gdyby powyższy link przestał kiedykolwiek działać, TUTAJ prezentuję zrzut ekranowy z powyższej strony. Jako ciekawostka - rate1_x – iks oznacza współrzędne kliknięcia w obrazek.
Ostatnio zauważyłem, że mimo wszystko jakieś roboty uruchamiają w prawidłowy sposób plik rate.php, prawidłowy - czyli nie zmieniają domyślnego nicka, nie wpisują emaila, po prostu uruchamiają plik rate.php ale... bez oddania głosu, system zlicza wtedy prawidłowy głos o wartości zero, przez kilka dni temu zmodyfikowałem skrypt w taki sposób, że teraz sprawdzana jest wartość oddanego głosu, a jeśli jest zero - zmienna $rate otrzymuje wartość "spamer". Jak dotąd nic się nie prześlizgnęło :)
### ??? sprawdzamy czy to nie spamer ##
if ($_POST['nick']=="catcher" && $_POST['email']=="" && $_POST['comment']=="" && $rate!="spamer")
// jeśli ukryte na "podpuchę" pola zostały zmienione - zakwalifikuj jako spam!
### ??? petla jesli nie spamer - start ###
{
### ??? sprawdzamy czy ktos z tego adresu ip juz nie glosowal kiedys na ten konkretny artykul ###
$result_rate=mysql_query("SELECT article_id, ip FROM www_rates
WHERE article_id='$_POST[article_id]' AND ip='" . $_SERVER[REMOTE_ADDR] . "'")
or die (mysql_error());
if (mysql_num_rows($result_rate)=='0')
### ??? jesli jest to pierwsze glosowanie
{
$add_record = "INSERT INTO www_rates (article_id, rate, datetime, ip)
values ('$_POST[article_id]' , '$rate' , " . mktime() . ", '$_SERVER[REMOTE_ADDR]')";
mysql_query ($add_record)
and print("
<META HTTP-EQUIV="Refresh" CONTENT="0;url=index.php?ln=" . $_POST[ln] . "&article_id=" . $_POST['article_id'] . "&vote_err=no">")
or die ("Can't add comment - " . mysql_error());
}
else
### ??? jesli juz glosowal ###
{
print("
<META HTTP-EQUIV="Refresh" CONTENT="0;url=index.php?ln=" . $_POST[ln] . "&article_id=" . $_POST['article_id'] . "
&vote_err=yes">");
}
}
### ??? petla jesli nie spamer - stop ###
include ('includes/footer.php');
?>
| Podobalo Ci sie? Chcesz mi jakos podziekowac? Wcisnij "Lubie To":
|
|
|
|
|
|
| |
Zabezpieczenie przed spamem - CAPTCHA Pamiętam, jak zaledwie w kilka godzin po wprowadzeniu na swojej stronie www możliwości pozostawiania komentarzy, zaczęły pojawiać się pierwsze wpisy o możliwości zakupu viagry, xanaxu, przedłużenia pewnych części ciała (nosa, hehe), wraz z adresami www. Oczywiście nie trudno było się zorientować, że wpisy te umieszczan [...]
|
System Zgloszeniowy UNITEL System zgłoszeniowy UNITEL został stworzony przeze mnie w miejsce przestarzałego, starego systemu zgłoszeniowego. Firma UNITEL, w momencie gdy w niej pracowałem, zajmowała się obsługą innych firm pod względem informatycznym. System miał zapewnić przyjecie i obsługę zgłoszeń serwisowych od klientów.
Główny nacisk, po [...]
|
Tworzenie w PHP własnego kanału RSS O zaletach własnych kanałów RSS nie będę nikogo przekonywał. Jeśli mimo wszystko ktoś nie zna ich zastosowania, opiszę to w osobnym artykule.
W przypadku konkretnie mojej strony www, w pliku article_add.php, odpowiedzialnym za dodawanie do bazy danych MySQL nowych artykułów, umieściłem dodatkową linijkę include("rss [...]
|
| |
|
Tagi: mysql, php, programowanie,
|
| |
|
|
|
|
|
|
| |
| |