Avatar billede h4x0r2tm Nybegynder
01. oktober 2003 - 03:12 Der er 21 kommentarer og
1 løsning

Simpel sql counter.

Søger en der keder sig, til at lave et forholdsvis simpelt script til mig.

Det skal blot gøre følgende:

Hente remote_addr, php_self og dato - og smide det i en mysql tabel.

Have en if sætning der tjekker om data'en eksisterer i forvejen.
- hvis ikke, så opret den.

Tjekke om datoen er mere end 24 timer gammel. Hvis den er, så slet den.

Tælle rækkerne og smide tallet i en variabel som kan echo'es på en website.

Kort sagt, en "true"-hit counter der gør brug af mySQL, og ikke tæller den samme ip to gange på det samme døgn.
Avatar billede morpheus Nybegynder
01. oktober 2003 - 03:47 #1
Well... I'm kinda bored
Avatar billede morpheus Nybegynder
01. oktober 2003 - 04:40 #2
Nå, det blev ikke særlig pænt, men det virker da!

http://bsd-box.dk/exp/counter.php
Avatar billede nicklasb Nybegynder
01. oktober 2003 - 07:26 #3
ja, som du selv siger, er det langt fra et færdigt og brugbart script.. Der er mange ting du burde have gjordt lettere, smartere, kortere osv..
Se fx bare din output-query ..
$count = mysql_query("SELECT `id` FROM `counter`") or die(mysql_error());
Hvirfor henter du id'et for alle posterne ud, når du på intet tidspunkt senere i scriptet bruger dette?!?
Avatar billede morpheus Nybegynder
01. oktober 2003 - 11:52 #4
Det er da underordnet om jeg laver en select på ID, ipaddr, tid eller side!
Avatar billede h4x0r2tm Nybegynder
01. oktober 2003 - 12:45 #5
Tror du ikke jeg kunne få dig til at cleane det lidt ?

Det skulle godt nok være simpelt, men også gerne overskueligt :)
Avatar billede morpheus Nybegynder
01. oktober 2003 - 13:54 #6
Hvad er det du er i tvivl om?
Avatar billede -xyz- Nybegynder
01. oktober 2003 - 14:59 #7
Du kunne også bare bruge en 24 timers cookie hvis det er fordi at du ikke vil have at den skal tælle besøgende mere end 1 gang i døgnet
Avatar billede nicklasb Nybegynder
01. oktober 2003 - 16:16 #8
morpheus -> Jo, det er underordnet hvilke af DE 4 informationer du søger på, da der ikke er vildt stor forskel på lægnden af værdierne.. Dog vil det da gøre en del på det endelige resultat hvis du har mange records der skal søges igennem, hvor det er underordnet hvilken du henter..
Men hvorfor ikke bare tælle på variablerne?!? (Se løsning lidt længere nede)

ved ikke hvem du mener h4x0r2tm.. men den kunne da "cleanes" meget, hvis det stod til mig.. Misforstå mig ikke morpheus.. er slet ikke ude efter dig som person, men ønsker vi ikke alle at lære noget, og især af vores fejl? ;D

For at optimere koden kunne vi gøre følgende ting:

1) Slette den første sql-select-query.. Det er irelevandte informationer du henter. Mere om det længere nede..

2) For at starte inderst i din while, kan vi starte med at slette din if-sætning som udelukkende har til opgave at update din tabel, hvis if-statementet er opfyldt. Hvorfor vil du update din tabel, når du alligevel opdatere alle felterne. Vil det så ikke være langt det letteste bare at slette dem alle, og så sætte ind lige meget hvad.. (Altså kan din checkvariabel $noupdate også slettes)

3) Nu har whilelykken ingen egentlig funktion, ud over at køre data igennem som ikke bliver valgt, da vi jo tidligere også slettede sql-statementet. Så den slettes

4) Tilbage står vi med de to sidste "kapitler".. For at forenkle opgaven en del, bytter vi nu rundt på disse, så alle de for gamle starter med at blive slettet! Hvis vi til vores delete-statement tilføjer at den også gerne må slette hvis den finder en post hvor id'et er lig den ip den pågældende computer har, uafhængigt af datoen, er vi sikker på at vores egen ip IKKE længere optræder i databasen, og vi har derfor ingen grund til at tjekke herpå.
Så if-sætningen rundt om, kan nu slettes, så vi kun står tilbage med to sql-statments.

ét til at slette records, og ét til at indsætte en enkelt.

Det sidste statement lader vi nu være (din select der viser hvor mange data der er i tabellen. Men for at optimere den en del, spørger vi nu udelukkende sql-serveren HVOR mange tilfælde der er. Som hovedregel skal du kun spørge om sådanne ting, hvis du alligevel ikke skal bruge dataene.

I dit eget eksempel gør det nu ikke så meget. Men glæder mig til at se en responstid på dit script når det engang bliver langt ind på en side, men bare små 10.000 hits dagligt.. SÅ er det pludseligt ikke så hurtigt mere, vil jeg gerne have lov at gætte på..

Et samlet script kunne nu se således ud:


<?php
/*
DESC: http://www.eksperten.dk/spm/408079
*/

//database
/*
CREATE TABLE `counter` (
  `id` int(11) NOT NULL auto_increment,
  `ipaddr` varchar(255) NOT NULL default '',
  `tid` int(11) NOT NULL default '0',
  `side` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM;
*/


include("dbconn.php");
dbConn();

$yourip  = $_SERVER['REMOTE_ADDR'];
$yoursite = $_SERVER['PHP_SELF'];
$timenow  = time();

$m24      = $timenow - 86400;
mysql_query('DELETE FROM counter WHERE tid < \'' . $m24 . '\' OR ipaddr = \'' . $yourip . '\'') or die(mysql_error());
mysql_query('INSERT INTO counter (ipaddr, tid, side) VALUES (\'' . $yourip . '\', \'' . $timenow . '\', \'' . $yoursite . '\')') or die(mysql_error());

$count = mysql_query('SELECT count(*) AS numbers FROM counter') or die(mysql_error());
$res  = mysql_fetch_array($count);
echo $res['numbers'];
?>

Som du kan se har jeg brugt en count i stedet for din num_rows.. Den skal du KUN bruge hvis du samtidig skal bruge alle de data du får ud.. Ellers er den funktion banlyst..!
Har ikke testet koden, da jeg ikke lige gider sidde at gemme den, og en database, på en server for at gøre det.. Men prøv den og kom med en fejlkode, hvis fejlen er en du ikke lige selv kan rette!
Håber alle fik lidt ud af rettelserne, og kunne se ideen i at rette op på koden frem for at skrive en ny :)

/Nicklas B.
Avatar billede nicklasb Nybegynder
01. oktober 2003 - 16:23 #9
og til sammenligning (og for at der også er noget ved at læse spørgsmålet engang i fremtiden, når scriptet er blevet slettet fra morpheus' server, kommer den gamle kode lige her:

          --------- BEMÆRK: EN GAMMEL KODE!! ---------
<?php
/*
DESC: http://www.eksperten.dk/spm/408079
*/

//database
/*
CREATE TABLE `counter` (
  `id` int(11) NOT NULL auto_increment,
  `ipaddr` varchar(255) NOT NULL default '',
  `tid` int(11) NOT NULL default '0',
  `side` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM;
*/


include("dbconn.php");
dbConn();

$res = mysql_query("SELECT * FROM `counter`") or die(mysql_error());

$noupdate = 0;

// Check om ip eksisterer
while($row = mysql_fetch_assoc($res)) {
    if($row['ipaddr'] == $_SERVER['REMOTE_ADDR']) {
        // Opdater tid og side
        $t_s_upd = mysql_query("UPDATE `counter` SET `tid` = ".time().", `side` = '".$_SERVER['PHP_SELF']."' WHERE `ipaddr` = '".$_SERVER['REMOTE_ADDR']."'") or die(mysql_error());
        $noupdate = 1;
    }
    // Vi sletter records der er 1 døgn gamle
    $m24 = time()-86400;
    $del = mysql_query("DELETE FROM `counter` WHERE `tid` < ".$m24) or die(mysql_error());
}


if($noupdate == 0) {
    // IP adressen eksisterer ikke, vi opretter den
    $new = mysql_query("INSERT INTO `counter` (`ipaddr`, `tid`, `side`) VALUES ('".$_SERVER['REMOTE_ADDR']."', ".time().", '".$_SERVER['PHP_SELF']."')") or die(mysql_error());
}
// Output
$count = mysql_query("SELECT `id` FROM `counter`") or die(mysql_error());
print mysql_num_rows($count);
print "<hr>";
show_source(__FILE__);
?>

          --------- BEMÆRK: EN GAMMEL KODE!! ---------

Bare en sammenligning af linierne giver et tydligt peg om at koden er en del hurtigere.. Men gennemlæser man koden, og begynder at analysere på de forskellige funktioner sammenlignet med nogle fiktive tal, for hvor mange data der skal hentes, som fx. 100.000 brugere, tør jeg godt gætte på at koden er reduceret med mange 1000% (hvad tid angår), uden at være bange for at overdrive..
En god idé til at få det bedste ud af sine koder, og lave det på den bedste måde, ville være at kigge php-manualen igennem.. Der står i bunden af beskrivelserne til hver funktion en masse kommentare fra forskellige programmøre.. Nogle bedre end andre..
Der står ved mange af funktionerne hvad et hurtigere alternativ kunne være.. Tjek dem ud engang.. Det giver meget.. :D
Avatar billede morpheus Nybegynder
01. oktober 2003 - 20:41 #10
Til mit eget forsvar vil jeg så lige sige: Kig på tidspunktet?!
Avatar billede morpheus Nybegynder
01. oktober 2003 - 20:41 #11
Og en gammel slagsang: If ain't broken, don't fix it!
Avatar billede h4x0r2tm Nybegynder
01. oktober 2003 - 20:51 #12
Har altid været modstander af den kliche.

Men tak for hjælpen, begge to.
Avatar billede nicklasb Nybegynder
01. oktober 2003 - 21:05 #13
morpheus -> Hvad er du så muggen over!?!
Er da lige glad med hvilken tid du har lavet det på.. Så gå i seng hvis du ikke kan lave noget ordentligt så sent.. Da latterligt at lave sådan en gang slamkode, hvis du KAN finde ud af at lave det bedre..
Og syntes nu heller ikke dit ordsprog holder særlig godt..
En bedre holdning til dette spørgsmål ville være "Hvorfor ikke optimere koden når den kan!?"
Det du havde skrevet var i hvert falde noget lort, og tror ikke den er særlig brugbar i "den virkelige" verden!
Avatar billede morpheus Nybegynder
01. oktober 2003 - 22:58 #14
Takker for point! :)
Avatar billede h4x0r2tm Nybegynder
02. oktober 2003 - 00:56 #15
Jeg har ændret :
mysql_query('DELETE FROM counter WHERE tid < \'' . $m24 . '\' OR ipaddr = \'' . $yourip . '\'') or die(mysql_error());

Til:
mysql_query('UPDATE cms_counter SET true_counter = \' true_counter+1 \' WHERE time < \'' . $m24 . '\'') or die(mysql_error());

Kan du forklare mig hvorfor den nu laver en ny række med ens data, fremfor at, hvis time < $m24, at lægge én til true_counter ... ?
Avatar billede h4x0r2tm Nybegynder
02. oktober 2003 - 00:57 #16
Du skal lige se bort fra at tabellen hedder noget andet...
Avatar billede nicklasb Nybegynder
02. oktober 2003 - 06:49 #17
vel fordi du beder den om kun at ændre dem der er ældre end 24 timer.. Du har vel selv været der inde flere gange gennem denne tidsperiode.. Derfor viser den dig flere gange.. Prøv at sætte samme where-statement på som jeg havde sat på i min..
Avatar billede Slettet bruger
02. oktober 2003 - 16:45 #18
Min intention er, at den skal gemme et "hit" fra en besøgende, 24 timer efter at han har været der igen.

Så troede jeg, at jeg bad scriptet lægge én til "true_counter", hvis hans ip var ældre end 24 timer.

Så troede jeg, at hvis der ikke var nogen ip ældre end 24 timer, ville den bare slet ikke gøre noget.

Er det ikke det, den gør i den query du skrev?
Avatar billede schaefner Juniormester
02. oktober 2003 - 16:48 #19
echo mysql_result(mysql_query("SELECT COUNT(*) FROM counter"),0);
Avatar billede nicklasb Nybegynder
02. oktober 2003 - 23:32 #20
pacr00n / h4x0r2tm ??! Hmm.. Hvis det er hvad jeg tror det er, ville jeg nok skynde mig at lukke den ene selv.. ellers ryger begge sikkert..
Avatar billede nicklasb Nybegynder
02. oktober 2003 - 23:33 #21
ellers misforstår jeg bare hvorfor pacr00n kommentere videre med flere uddybende spørgsmål.. Naa..
Avatar billede kappel Nybegynder
07. marts 2004 - 11:57 #22
h4x0r2tm >>

Hej jeg leder efter det samme, jeg er blevet træt af chart og peak, de er så langsommme. Gider du smide den kode som du endte med at bruge

Mvh Kappel (og på forhånd tak)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester