[PHP] webcounter terug leeg??!!

Pagina: 1
Acties:

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
hoi,
ik heb volgende code voor mijn website, bezoekersteller geschreven..

alles ging goed, er waren ongeveer 220 bezoekers (op 24u)...
maar ineens stond de teller terug op 3, en was deze dus gereset geweest..
zou het kunnen dat er misschien 2 mensen tegelijk in m'n files schreven?
Zodat hij volledig leeg was, of wat zou dit probleem veroorzaakt hebben?

mijn code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<?php
        // de log files die gebruikt worden 
        $filelocation="cnt.db"; 
        $iplog="log.db"; 
        
        // pakt de  ip van de bezoeker werkt ook op f2s 
        $ip= $HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"]; 
        
        // leest de ip uit het logbestand 
        $logopen = fopen($iplog,"r"); 
        $ipfromlog = fread($logopen, filesize($iplog)); 
        fclose($logopen); 
        
        
        // leest de aantal hits uit de logbestand 
            $newfile = fopen($filelocation,"r"); 
            $content = fread($newfile, filesize($filelocation)); 
            fclose($newfile); 
        
        
        // de aantal cijfers dat wordt weergegeven 
        
        if ($content >= 10000)
            {
                $digits = 5;
            }
        else if ($content >= 1000)
            {
                $digits = 4;
            }
        else if ($content >= 100)
            {
                $digits = 3;
            }
        else if ($content >= 10)
            {
                $digits = 2;
            }
        else if ($content >= 1)
            {
                $digits = 1;
            }
        else
            {
                $digits = 6;    
            }
        
        // Als er een nieuwe bezoeker is 
        // (IP bezoeker is niet gelijk aan de IP van de log file) 
        // Dan doe het volgende... 
        
        if ($ip != $ipfromlog ) {    
        
        // aantal hits + 1 
        $newfile = fopen($filelocation,"w+"); 
        $content++; 
        fwrite($newfile, $content); 
        fclose($newfile); 
        
        // log de IP van de laatste bezoeker 
        $openlog = fopen($iplog,"w+"); 
        fwrite($openlog, $ip); 
        fclose($openlog); 
        } 
        
        // dit krijg je op het beeld te zien
        echo "<p class=\"bezoekers\" align=\"center\">bezoekers #: \n";
        ?></u>
        <b><?
        echo sprintf ("%0"."$digits"."d",$content)."";
        ?> </b>

Verwijderd

flock

lees dat eens door..

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if ($content >= 10000) 
            { 
                $digits = 5; 
            } 
        else if ($content >= 1000) 
            { 
                $digits = 4; 
            } 
        else if ($content >= 100) 
            { 
                $digits = 3; 
            } 
        else if ($content >= 10) 
            { 
                $digits = 2; 
            } 
        else if ($content >= 1) 
            { 
                $digits = 1; 
            } 
        else 
            { 
                $digits = 6;     
            }


kan ook zo

PHP:
1
    $digits = strlen($content);


:P

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
hehe, ja... je hebt gelijk :)
wel wat duf van mij ;)

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
Ja, maar als ik die flock gebruik..
kan het dan zijn dat er bepaalde bezoekers niet geregistreerd worden?

Verwijderd

het probleem is waarschijnlijk dat je geen foutafhandeling hebt als fopen/fread niet werken. Dan blijft $content dus 0, wordt opgehoogd met 1, en wordt dus weer weggeschreven als 1: gereset dus. Je moet de fopen-aanroepen in een while loop zetten die loept zolang de geretourneerde filepointer NULL is. Het is wel aan te raden om een maximaal aantal iteraties te forceren in de while loop, en om tussen elke poging een usleep van een paar milliseconden te doen, om te zorgen dat je niet eeuwig blijft loepen, en om het script dat de lock op de file heeft de tijd te geven te beindigen.

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
op deze manier dan:
PHP:
1
2
3
4
5
6
        do {
            $newfile = fopen($filelocation,"r");
            sleep(10);
        } while ($newfile == NULL);
            $content = fread($newfile, filesize($filelocation)); 
            fclose($newfile);

en
PHP:
1
2
3
4
5
6
7
8
        // aantal hits + 1 
        do {
            $newfile = fopen($filelocation,"w+");
            sleep(10);
        } while ($newfile == NULL);
        $content++; 
        fwrite($newfile, $content); 
        fclose($newfile);

:?

Verwijderd

Dat is'm. En als je helemaal zeker wilt weten dat je geen counts kwijtraakt, dan moet je hem maar 1 keertje openen met r+ als vlag, en dan pas nadat je geschreven hebt hem weer sluiten. Anders loop je het risico dat een tweede instantie van het script iets wegschrijft in de file tussen het lezen en schrijven door.
Let wel: ik ben ervan uitgegaan dat PHP automatisch een file locked als ie er naar gaat schrijven, maar dat weet ik niet helemaal zeker, kon het zo snel niet vinden. Als dat niet zo is, moet je zoals xtentic zegt expliciet locken met flock nadat je een pointer hebt.
Oh, en je moet usleep gebruiken, niet sleep want 10 seconden wachttijd is misschien een beetje lang. Ik zou eerst 'ns met usleep( 1000 ) beginnen, dan probeer je het elke milliseconde. Zorg dan dat, als je na 25 keer proberen of zo nog steeds geen file-pointer hebt, het script een foutmelding produceert. Komt dat vaak voor, dan kun je het aantal keren dat je het probeert verhogen, of de usleep tijd tussen de pogingen.
Oh ja, en je moet nog ff een limiet in de do-loop bouwen, dat ie het niet oneindig blijft proberen, dus bv "} while ($newfile == NULL && $tries++ < 25 );"

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

Verwijderd schreef op 17 oktober 2002 @ 11:34:
[kan ook zo

PHP:
1
    $digits = strlen($content);


:P

Is imho nog steeds erg lelijk eigenlijk... $content is dan wel een string in dit geval, dus in principe kan het wel, maar als je speciaal hiervoor zou moeten casten vindt ik het wel heel smerig. Dit getal is immers ook erg simpel te berekenen met 10log.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
wat bedoel je precies met lelijk en smerig?
Is toch wel een goede manier zo... ofniet?

of hoe zou jij het dan doen?

Verwijderd

Je hoeft daarvoor niet te casten, want fread geeft een string terug, dus je moet hoedanook casten van string naar int. Bovendien, dit is PHP, als je je druk maakt over casts moet je in een lower-level taal gaan werken waar je alles zelf in de hand hebt.

Verwijderd

Als je een file leest hoef je hem niet te locken,
alleen bij het schrijven

Verwijderd

nog beter is gewoon een mysql server aanspreken en de waarde met 1 verhogen...

/me ziet dat zijn nuttige post gewaardeerd wordt :D
Pagina: 1