PHP števec obiskov - MySQL različica


Uvod

Ker se je staremu števcu od časa do časa zmešalo in ker vzroka napake nisem odkril, sem napravil različico števca, ki za svoje delovanje ne uporablja datoteke, ampak MySQL bazo. Ideja je torej ostala enaka, spremenila se je izvedba. Ker je MySQL bolj ranljiv, sem povsod nametal varnostne ukrepe. Več o njih v korakih skozi kodo.

Ideja

Ko obiskovalec pride na stran, števec najprej prebere tabelo v bazi in počisti starejše vnose od časovne omejitev (če tabel ni, jih samodejno ustvari). Nato preveri, če je obiskovalčev IP še vedno prisoten. Če IPja v datoteki ni, prišteje 1 in doda obiskovalčev IP v datoteko. Tako je omogočeno samodejno čiščenje starih vnosov in pravično štetje.

Koraki skozi kodo

Najprej je potrebno definirati nekaj spremenljivk. Spremenljivka $stevec_blok definira čas blokade v minutah. Če bo obiskovalec ponovno obiskoval stran v tem intervalu, se to ne bo prištelo k celotnem številu obiskov. Polje $stevec_moj_ip vsebuje IPje, ki bi jim radi preprečili doprinos k štetju, vanj lahko shranite poljubno število IPjev.


$stevec_blok 
720//čas blokade v minutah
$stevec_moj_ip = array('prvi_blokiran_ip','drugi_blokiran_ip','itd.');

Opombe:

  • Čas blokade v minutah lahko nastavite tudi kot decimalno število

IP dobi skripta preko preverjanja spremenljivke $_SERVER['REMOTE_ADDR']. Če je računalnik slučajno za proxy strežnikom, se za IP uporabi njegov lastni IP in ne IP proxya s pomočjo spremenljivke $_SERVER['HTTP_X_FORWARDED_FOR']


$stevec_ip 
$_SERVER['REMOTE_ADDR'];

//preveri proxy
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && ($_SERVER['HTTP_X_FORWARDED_FOR']!="")) {
$stevec_ip $_SERVER['HTTP_X_FORWARDED_FOR'];
}
elseif(
$stevec_ip=="127.0.0.1") {
$stevec_ip "127.0.0.1";
}

Povezava z bazo

Povezava se mora klicati znotraj vsake funkcije. Zaradi preglednosti lahko te vrstice shranite v ločeno datoteko (recimo db.php) in nato kličete preko funkcije include(). Skozi kodo bom te vrstice izpuščal, da bo preglednost večja.


//Poveži se z bazo
$dbhost 'localhost';
$dbuser 'uporabnik_baze';
$dbpass 'vase_geslo';
mysql_connect($dbhost$dbuser$dbpass) or die ("");
$dbname 'ime_baze';
mysql_select_db($dbname);

funkcija Stevec()

Funkcija števec je glavna funkcija, ki se kliče ob zahtevku. Za preverjanje blokiranih IPjev, se uporablja funkcija in_array(), ki vrne FALSE, če IP ni najden znotraj polja. Če IP ni najden, se izvrši funkcija PreveriIP. Na koncu funkcije se izvrši še prikaz števca. Tukaj je oblikovanje shranjeno v števcu, lahko pa samo izpisujete spremenljivke in jih oblikujete kasneje.


function Stevec($ip,$moj_ip,$blok) {
    
//Poveži se z bazo
    //glej zgoraj
    //Če ne dostopam iz IPja, ki je moj, kliči funkcijo PreveriIP()
    
if(!in_array($ip,$moj_ip)) {
        
PreveriIP($ip,$blok);
    }
    
//Prikaži obiske
    
$sql "SELECT `obiski`,`datum` FROM `stevec_obiski`";
    
$q mysql_query($sql) or die();
    if(
mysql_num_rows($q) == 0) {
        echo 
'Napaka števca!';
    }
    else {
        
$myrow mysql_fetch_array($q);
        echo 
'<p class="center"><span class="malo">Si obiskovalec številka</span><br /><b>'.$myrow['obiski'].'</b><br /><span class="malo">od '.$myrow['datum'].'</span></p>' "\n";
    }
}

Opombe:

  • Funkcija die() ne vrne nobene vrednosti. To je zaradi varnostnih razlogov. Če bi pa obiskovalce vseeno radi opozorili, da je stran nehala delovati zaradi števca, pa lahko vnesete besedilo: die("besedilo")

Funkcija PreveriIP()

Funkcija izgleda na prvi pogled dokaj zakomplicirano, zato sem jo razbil na več delov. Kot argument sprejema spremenljivko $ip, ki je IP obiskovalca in $blok, ki je čas blokade v minutah. Spremenljivki $cas se določi UNIX timestamp, to je čas merjen v sekundah od 1.1.1970 00:00:00 GMT. Spremenljivka $ip je obdelana s mysql_real_escape_string(). To je varnostni ukrep, če bi se slučajno komu po čudežu posrečilo namesto IPja poslati zlobno kodo. Če niste paranoik, lahko to tudi izbrišete.


function PreveriIP($ip,$blok) {
//Poveži se z bazo
//glej zgoraj
//zaščiti se pred hekerji (za vsak slučaj)
$ip mysql_real_escape_string($ip);
//Dobi trenuten čas
$cas time();

Koda nato preveri, če tabela že obstaja, če ne jo naredi. Ker je ta korak potreben le enkrat, lahko po ustvarjeni tabeli ta del kode izbrišete.


//Preveri, če tabela obstaja
$sql "SHOW TABLES LIKE 'stevec_obiski'";
$q mysql_query($sql);
if(
mysql_num_rows($q) == 0) {
//Če tabela ne obstaja, jo napravi
$sql "CREATE TABLE `stevec_ip` (`ip` VARCHAR(32) NOT NULL, `datum` VARCHAR(32) NOT NULL)";
$q mysql_query($sql) or die("Tabele ni bilo mogoče napraviti!");
}

Sledi izbor vseh vnosov iz tabele. Če je ta prazna, vanjo zapiše prvi obisk in pokliče funkcijo Stej().


//Izberi vse vnose iz tabele
$sql "SELECT `ip`,`datum` FROM `stevec_ip`";
$q mysql_query($sql);
if(
mysql_num_rows($q) == 0) {
//Če ni obiskov, zapiši prvi obisk
$sql "INSERT INTO `stevec_ip` (`ip`,`datum`) VALUES ('$ip','$cas')";
$r mysql_query($sql);
//In kliči funkcijo Stej
Stej();        
}

V nasprotnem primeru ena za eno počisti vse vnose, ki so starejši od intervala definiranega s $blok. Tako čiščenje ohranja tabelo majhno. Znotraj tega bloka se izvrši tudi preverjanje, če je IP že vpisan. Če ni, se doda in pokliče funkcija Stej().


else {
//V nasprotnem primeru počisti vse vnose, ki so starejši od časa definiranega s $blok
while($myrow mysql_fetch_array($q)) {
$datum $myrow['datum'];
$myrowip $myrow['ip'];
if((
$datum+$blok*60)<=$cas) {
$sql "DELETE FROM `stevec_ip` WHERE `ip`='$myrowip' AND `datum`='$datum' LIMIT 1";
$r mysql_query($sql);
}
}
$sql "SELECT `ip` FROM `stevec_ip` WHERE `ip`='$ip'";
$s mysql_query($sql);
if(
mysql_num_rows($s) == 0) {
//Sedaj dodaj IP, če ta ne obstaja v tabeli
$sql "INSERT INTO `stevec_ip` (`ip`,`datum`) VALUES ('$ip','$cas')";
$t mysql_query($sql);
//In kliči funkcijo Stej
Stej();
}
//tu je konec funkcije Stevec()
}

Funkcija Stej()

Sedaj je na vrsti funkcija Stej(). Razdelil jo bom na več kosov. Najprej spet povezava z bazo. Navodila vidite zgoraj.


function Stej() {
//Poveži se z bazo
//glej zgoraj

Sledi preverjanje baze. Če tabela stevec_obiski ne obstaja, jo funkcija napravi. To vrstico lahko kasneje, ko je tabela narejena izbrišete. Datum začetka štetja je nastavljen v spremenljivki $datum in se samodejno nastavi kot trenutni datum. Nastavite lahko poljubnega.


//Preveri, če tabela obstaja
$sql "SHOW TABLES LIKE 'stevec_obiski'";
$q mysql_query($sql);
if(
mysql_num_rows($q) == 0) {
//Če ne obstaja, jo naredi, datum je datum začetka štetja, lahko nastavite tudi svoj datum
$datum date("j\.n\.Y");
$sql "CREATE TABLE `stevec_obiski` (`obiski` INT(16) NOT NULL, `datum` VARCHAR(32) NOT NULL DEFAULT '$datum')";
$q mysql_query($sql) or die();
}

Sledi pridobivanje števila obiskov. Če jih še ni, se zapiše prvi obisk, v nasprotnem primeru pa za ena večji


    
//Dobi število obiskov
    
$sql "SELECT `obiski` FROM `stevec_obiski`";
    
$q mysql_query($sql);
    if(
mysql_num_rows($q) == 0) {
        
//Če ni obiskov, zapiši prvi obisk
        
$sql "INSERT INTO `stevec_obiski` (`obiski`) VALUES ('1')";
        
$q mysql_query($sql);
    }
    else {
        
//V nasprotnem primeru zapiši za ena večji obisk
        
$myrow mysql_fetch_array($q);
        
$newrow $myrow['obiski'] + 1;
        
$sql "UPDATE `stevec_obiski` SET `obiski`='$newrow'";
        
$q mysql_query($sql);
    }
}

To je vse. Navodila kako skripto usposobiti in izvorno kodo najdete v desnem stolpcu. Če imate predloge za optmizacijo, mi jih sporočite na e-mail (povezavo najdete na koncu strani)


Copyright 2002-2012 Andrej Mernik, vsa vprašanja na e-mail. Pa še Posebna zahvala. Stran je bojda narejena v skladu s XHTML standardi. Za spremljanje novosti lahko uporabite tudi RSS.

Hitre povezave

Uporaba skripte za komercialno uporabo (služenje denarja) je strogo prepovedana!

Izvorna koda

Navodila za uporabo

Zgornjo skripto si prenesite na disk in jo preimenujte v stevec.php. Spremenite nastavitve in dodajte IPje, ki bi jih želeli blokirati. Za prikaz skripte uporabite le še funkcijo include("/pot/do/stevca/stevec.php"); oziroma include("X:\\pot\\do\\stevec.php"); za Windows sisteme (X: črka diska) in prikažite izpis s kodo:
Stevec($stevec_ip,
$stevec_moj_ip,
$stevec_blok);
.

Kako najti pravo pot?

Nahaja se v ukazu: getenv("DOCUMENT_ROOT");. Dodajte le še podmape do števca.