Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Anti Flood
Forum PHP.pl > Forum > PHP
grzesiek25
Mam taki o to skrypt anty "floodowy"
  1. <?php
  2. if (!isset($_SESSION)) {
  3. }
  4. if($_SESSION['last_session_request'] > time() - 3){
  5. $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
  6. if ($ip == "") $ip = $_SERVER["REMOTE_ADDR"];
  7. $db = mysql_connect ("localhost", "login", "hasło");
  8. mysql_select_db ("baza");
  9. mysql_query("INSERT INTO antyflood (IP, TIME) VALUES ('$ip', NOW())");
  10. $timeout = 30; // minutes
  11. $cutoff = (mktime()-($timeout*60));
  12. $query = "DELETE FROM antyflood WHERE TIME < " . $cutoff;
  13. $resuly = mysql_query($query);
  14. }
  15. $_SESSION['last_session_request'] = time();
  16. ?>


Problem z nim polega na tym że nie kasuje wpisu automatycznie po tych 30 minutach, jest na to jakaś rada ?
wiele sposobów przetestowałem i bez rezultatu.
be2k
taki krotki skrypt i tyle bledow winksmiley.jpg

po pierwsze:
  1. <?php
  2. if (!isset($_SESSION)) {
  3. }
  4. ?>

to jest bez sensu, bo zawsze if bedzie spelniony. Dopoki nie wystartujesz z sesja, nie bedziesz mial zadnych zmiennych sesyjnych.

po drugie:
  1. <?php
  2. $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
  3. ?>

pobiera ip uzytkownika jesli ten laczy sie przez proxy, a ze nie zawsze tak jest to powinienes sprawdzac czy jest ta zmienna, a jesli jej nie ma to brac ip z
  1. <?php
  2. $ip = $_SERVER["REMOTE_ADDR"];
  3. ?>

btw. testowales to u siebie lokalnie i Ci dzialalo pobieranie IP questionmark.gif

po trzecie, porownaj sobie jak wyglada zmienna:
  1. <?php
  2. $cutoff = (mktime()-($timeout*60));
  3. ?>

a co zwraca mysql'owy NOW(), zobaczysz ze 'delikatnie' sie roznia...
grzesiek25
Pokombinowałem troche nad tym kodem i zmieniłem funkcje mktime na taką w jakiej zapisuje prawidłowo datę i czas czyli teraz wygląda tak samo jak funkcja NOW()

dodałem taki kod
  1. <?php
  2. $czas = date("Y-m-d H:i:s");
  3. $secs = 1800;
  4. $roznica = ($czas - $secs);
  5. mysql_query("DELETE FROM antyflood WHERE TIME < $roznica");
  6. ?>

jednak dalej bez efektów...

PS. pobieranie IP działa mi bez zarzutu, dodawanie wpisu do bazy po wystąpieniu floodu również gdy nastąpi ponad 3 zapytania na sekundę, jedyny problem to usuwanie wpisów które są już w bazie od 30 minut
nithajasz
... i teraz odejmujesz (2008-05-28 12:14:15 - 1800) widzisz w tym sens?

Zmień to na :

  1. <?php
  2. $czas = now();
  3. $secs = 1800;
  4. $roznica = ($czas - $secs);
  5. mysql_query("DELETE FROM antyflood WHERE TIME < $roznica");
  6. ?>


i w zależności jak masz zapisaną w bazie pozycję antyflood to albo odejmuj od razu lub jeśli masz format datatime to sobie dodaj ta linijkę przed zapytaniem:

  1. <?php
  2. $cutoff = date("Y-m-d H:i:s", $roznica);
  3. ?>
grzesiek25
Nie wiem czy dobrze to poskładałem, wygląda to w ten sposób
  1. <?
  2. if (!isset($_SESSION)) {
  3. }
  4. if($_SESSION['last_session_request'] > time() - 3){
  5. $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
  6. if ($ip == "") $ip = $_SERVER["REMOTE_ADDR"];
  7. $db = mysql_connect ("localhost", "login", "hasło");
  8. mysql_select_db ("baza");
  9. mysql_query("INSERT INTO antyflood (IP, TIME) VALUES ('$ip', NOW())");
  10. $czas = now();
  11. $secs = 1800;
  12. $roznica = ($czas - $secs);
  13. $cutoff = date("Y-m-d H:i:s", $roznica);
  14. $query = "DELETE FROM antyflood WHERE TIME < " . $cutoff;
  15. $resuly = mysql_query($query);
  16. }
  17. $_SESSION['last_session_request'] = time();
  18. ?>


PS. format czasu w bazie to DATETIME

jednak teraz pojawia się błąd

Fatal error: Call to undefined function now()
nithajasz
Zamień funkcję now() na time() i powinno być dobrze..
grzesiek25
Cytat(nithajasz @ 28.05.2008, 12:47:54 ) *
Zamień funkcję now() na time() i powinno być dobrze..


Zmieniłem, teraz już błędu nie ma ale nadal wpisu nie kasuje mimo że zmieniłem czas dodania wpisu odejmując ponad pół godziny.
nithajasz
  1. <?php
  2.  
  3. if($_SESSION['last_session_request'] > time() - 3){
  4. $ip = $_SERVER[&#092;"HTTP_X_FORWARDED_FOR\"];
  5. if ($ip == &#092;"\") $ip = $_SERVER[\"REMOTE_ADDR\"];
  6. $db = mysql_connect (&#092;"localhost\", \"login\", \"hasło\");
  7. mysql_select_db (&#092;"baza\");
  8. mysql_query(&#092;"INSERT INTO antyflood (IP, TIME) VALUES ('$ip', NOW())\");
  9. $minutes = round(1800/60);
  10. $query = &#092;"DELETE FROM antyflood WHERE TIME < SUBDATE( NOW( ) , INTERVAL \".$minutes.\" MINUTE)\"; 
  11. $resuly = mysql_query($query);
  12. }
  13. $_SESSION['last_session_request'] = time();
  14. ?>


Powinno działać.. Ale jak nie będzie to pisz bo to przerabiane tak na szybko.

Ogólnie to ja bym zrezygnował z pola datetime i zmienił je na timestamp jakoś łatwiej się operuje na nim.
be2k
jak nie wiesz dlaczego cos nie dziala to debuguj, wyswietlaj bledy itp to naprawde pomaga.

prawdopodobnie nie kasuje ci rekordow bo masz bledne zapytanie, dodaj apostrofy:
  1. <?php
  2. $query = "DELETE FROM antyflood WHERE TIME < '" . $cutoff . "'";
  3. ?>


i wywal to:
  1. <?php
  2. if (!isset($_SESSION))
  3. {
  4. }
  5. ?>

a zostaw samo:
  1. <?php
  2. ?>
nithajasz
[quote name='be2k' date='28.05.2008, 13:30:00 ' post='476300']
jak nie wiesz dlaczego cos nie dziala to debuguj, wyswietlaj bledy itp to naprawde pomaga.

prawdopodobnie nie kasuje ci rekordow bo masz bledne zapytanie, dodaj apostrofy:
  1. <?php
  2. $query = &#092;"DELETE FROM antyflood WHERE TIME < '\" . $cutoff . \"'\";
  3. ?>


To zapytanie i tak nie pójdzie jak chcesz porównać string do liczby?
be2k
Cytat(nithajasz @ 28.05.2008, 13:34:59 ) *
To zapytanie i tak nie pójdzie jak chcesz porównać string do liczby?

nie string do liczby tylko string do stringa
przeciez w kodzie ma:
  1. <?php
  2. $czas = time(); //poprawione z now();
  3. $secs = 1800;
  4. $roznica = ($czas - $secs);
  5. $cutoff = date("Y-m-d H:i:s", $roznica);
  6. ?>
grzesiek25
Niestety podane przez was metody nie działają.
nithajasz
Cytat(be2k @ 28.05.2008, 13:43:01 ) *
nie string do liczby tylko string do stringa
przeciez w kodzie ma:
  1. <?php
  2. $czas = time(); //poprawione z now();
  3. $secs = 1800;
  4. $roznica = ($czas - $secs);
  5. $cutoff = date(&#092;"Y-m-d H:i:s\", $roznica);
  6. ?>


Fakt, coś mi się pomerdało smile.gif
be2k
Cytat(grzesiek25 @ 28.05.2008, 13:49:14 ) *
Niestety podane przez was metody nie działają.


a sprawdzasz to w jakikolwiek sposob? jak wygladaja rekordy w bazie?
jak wyglada zapytanie ktore wykonujesz aby usunac rekordy (echo())?
jestes pewny ze to zapytanie sie poprawnie wykonuje?
moze mysql zwraca jakis blad a ty o tym nie wiesz bo nawet tego nie sprawdzasz?
grzesiek25
Cytat(be2k @ 28.05.2008, 13:56:42 ) *
a sprawdzasz to w jakikolwiek sposob? jak wygladaja rekordy w bazie?
jak wyglada zapytanie ktore wykonujesz aby usunac rekordy (echo())?
jestes pewny ze to zapytanie sie poprawnie wykonuje?
moze mysql zwraca jakis blad a ty o tym nie wiesz bo nawet tego nie sprawdzasz?


Zapytanie dodające wpis do bazy wykonuje się poprawnie
w bazie wygląda to tak
IP xx.xx.xx.xx
TIME 2008-5-28 14:00:27
zapytanie kasujące rekordy to

  1. <?php
  2. DELETE FROM antyflood WHERE TIME < '" . $cutoff . "'";
  3. ?>


włącze pełny error reporting i może czegoś więcej sie dowiem
be2k
Cytat(grzesiek25 @ 28.05.2008, 14:06:04 ) *
  1. <?php
  2. DELETE FROM antyflood WHERE TIME < '" . $cutoff . "'";
  3. ?>

chodzilo mi o to zebys wyswietlil to zapytanie, czyli echo("DELETE FROM...") zeby zobaczyc jak wyglada z wartoscia zmiennej ktora tam wstawiasz smile.gif
grzesiek25
Cytat(be2k @ 28.05.2008, 14:10:59 ) *
chodzilo mi o to zebys wyswietlil to zapytanie, czyli echo("DELETE FROM...") zeby zobaczyc jak wyglada z wartoscia zmiennej ktora tam wstawiasz smile.gif


To zapytanie wyświetla mi error

Parse error: syntax error, unexpected T_ECHO

próbowałem tak
  1. <?php
  2. $query = echo "DELETE FROM antyflood WHERE TIME < '" . $cutoff . "'";
  3. i
  4. $query = echo ("DELETE FROM antyflood WHERE TIME < '" . $cutoff . "'");
  5. ?>

w obu przypadkach ten sam błąd
em1X
Lepiej pokaż jak wygląda struktura Twojej bazy. Bo jeżeli time jest typu varchar no ciekaw jestem jak mają działania matematyczne na niej zadziałać. Poza tym nazwy pól lepiej owijać w cudzysłów, bo słowo time może być słowem kluczowym w starszych wersjach.

  1. <?php
  2. // po ilu minutach usunąć
  3. $_time = 30;
  4.  
  5. // usuwamy rekordy
  6. mysql_query('delete from `tabela` where `time` + '.($_time * 60).') < '.time()) or die(mysql_error());
  7. ?>
grzesiek25
Cytat(em1X @ 28.05.2008, 14:26:16 ) *
Lepiej pokaż jak wygląda struktura Twojej bazy. Bo jeżeli time jest typu varchar no ciekaw jestem jak mają działania matematyczne na niej zadziałać. Poza tym nazwy pól lepiej owijać w cudzysłów, bo słowo time może być słowem kluczowym w starszych wersjach.

  1. <?php
  2. // po ilu minutach usunąć
  3. $_time = 30;
  4.  
  5. // usuwamy rekordy
  6. mysql_query('delete from `tabela` where `time` + '.($_time * 60).') < '.time()) or die(mysql_error());
  7. ?>


tak wygląda tabelka

  1. <?php
  2. CREATE TABLE `antyflood` (
  3. `IP` char(32) NOT NULL default '',
  4. `TIME` datetime NOT NULL default '0000-00-00 00:00:00',
  5. PRIMARY KEY (`IP`)
  6. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  7. ?>

przy twoim kodzie TIME nie powinno mieć przypadkiem ustawionego samego typu time ?
be2k
Cytat(grzesiek25 @ 28.05.2008, 14:18:36 ) *
To zapytanie wyświetla mi error

Parse error: syntax error, unexpected T_ECHO

próbowałem tak
  1. <?php
  2. $query = echo "DELETE FROM antyflood WHERE TIME < '" . $cutoff . "'";
  3. i
  4. $query = echo ("DELETE FROM antyflood WHERE TIME < '" . $cutoff . "'");
  5. ?>

w obu przypadkach ten sam błąd


chlopie! smile.gif wklej tutaj wynik funkcji echo "DELETE FROM..."
podstawy, podstawy, podstawy...
grzesiek25
Cytat(be2k @ 28.05.2008, 14:39:43 ) *
chlopie! smile.gif wklej tutaj wynik funkcji echo "DELETE FROM..."
podstawy, podstawy, podstawy...


oto on
  1. <?php
  2. DELETE FROM antyflood WHERE TIME < '2008-05-28 14:12:27'
  3. ?>
be2k
Cytat(grzesiek25 @ 28.05.2008, 14:48:55 ) *
oto on
  1. <?php
  2. DELETE FROM antyflood WHERE TIME < '2008-05-28 14:12:27'
  3. ?>


i co, to nie dziala?
jak wersje mysl'a uzywasz? u mnie na 5.0.22 to dziala.
wez wstaw sobie przykladowy rekord w tej tabeli z data mniejsza od np. tej co powyzej i wywolaj to zapytanie. to musi dzialac.

pozatym twoja struktura tabeli jest bledna bo po co IP jest typu char o rozmiarze 32 - widziales kiedys IP tylu znakowy.
druga sprawda to bledem jest to, ze to pole jest kluczem glownym, bo zapisujesz do tej tabeli IP ktore na pewno juz w niej wystepuje.
grzesiek25
Cytat(be2k @ 28.05.2008, 15:05:52 ) *
i co, to nie dziala?
jak wersje mysl'a uzywasz? u mnie na 5.0.22 to dziala.
wez wstaw sobie przykladowy rekord w tej tabeli z data mniejsza od np. tej co powyzej i wywolaj to zapytanie. to musi dzialac.

pozatym twoja struktura tabeli jest bledna bo po co IP jest typu char o rozmiarze 32 - widziales kiedys IP tylu znakowy.
druga sprawda to bledem jest to, ze to pole jest kluczem glownym, bo zapisujesz do tej tabeli IP ktore na pewno juz w niej wystepuje.


5.0.45

Wstawiłem taki rekord z datą mniejszą uruchomiłem skrypt bez efektu, wykonanie polecenia w edytorze mysql również.
nithajasz
Dziwne mi na tej samej wersji działa, aż sprawdziłem dokładnie...
rzymek01
grzesiek25, użyj lepiej timestampa zamiast datetime,
naprawdę lepiej się na nim operuje -> szybkość, wygoda, dostępność w PHP kilku wbudowanych funkcji, np. strftime, strptime, strtotime winksmiley.jpg
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.