Mulla on kävijälaskuri, jossa on online-ennätys ja ennätyksentekopvm. Se näyttää kuitenkin tyhjenevän vähän väliä :(
Koodi on tällainen:
<?php // This is the IP address of our visitor $ip_addr = $_SERVER['REMOTE_ADDR']; // Edit this variable // path of your online.dat file is : $file = '/var/www/virtual/...../online/online.dat'; // Get our array from the online.dat file $online = file_get_contents($file); $online = unserialize($online); // Update the entry for this visitor $online['visitors'][$ip_addr] = time(); // this is the number of seconds after // which a user is considered "idle" $timeout = 600; // 600 seconds = 10 minutes foreach($online['visitors'] as $key => $val) { if($val < (time() - $timeout)) { unset($online['visitors'][$key]); } } // Current number of visitors online $total_visitors = count($online['visitors']); // Update our record if necessary if($total_visitors > $online['record']['number']) { $online['record']['number'] = $total_visitors; $online['record']['time'] = time(); } $record_number = $online['record']['number']; $record_time = $online['record']['time']; /* POISTETTU NÄKYVISTÄ echo 'Online nyt: '.$total_visitors.'<br />'; */ echo 'Ennätys: '.$record_number.'<br />Ennätys pvm: '.gmdate('d.m.Y', $record_time); // Write the new data back to our file $handle = fopen($file, 'w'); fwrite($handle, serialize($online)); fclose($handle); ?>
Kannattaa lukita tiedosto flockin avulla ennen käpistelyä, itselläni oli sama ongelma joitakin vuosia takaperin ja se korjaantui kun aloin lukitsemaan tiedostoa. Vika johtuu sinullakin melko varmasti siitä, että tiedostoa lukiessa / siihen kirjoittaessa tiedostoon kohdistuu myös toinen luku/kirjoitusyritys ja homma menee poskelleen.
Justjust. Eli muutanko mä ton koodin lopun näin:
// Write the new data back to our file $handle = fopen($file, 'w'); if (flock($handle, LOCK_EX)) { // do an exclusive lock fwrite($handle, serialize($online)); flock($handle, LOCK_UN); // release the lock } else { echo "Couldn't lock the file !"; } fclose($handle); ?>
Vai pitääkö tohon lukitukseen luoda erikseen oma joku väliaikaistiedosto?
// Write the new data back to our file $handle = fopen($file, 'w'); fwrite($handle, serialize($online)); fclose($handle); flock($file); ?>
Tämän pitäisi toimia.
Kuulostaa pelottavalta, tiedoston tyhjentyminen. Pitäisiköhän minunkin käyttää tätä systeemiä sivuillani, siellä on foorumi, artikkelialue ja kaikkea muutakin kriittisesti tiedostojen lukuun ja kirjoitukseen perustuvaa. En vielä ole niitä julkaissut niin en ole nähnyt mitä kauheuksia tapahtuu jos kaksi lukee yhtäaikaa.
lukea voi vaikka n^2 käyttäjää yhtäaikaa, mutta silloin kun tulee tiedoston luku kirjoittamista varten samalla kun toinen prosessi kirjoittaa tiedostoon tai kun kaksi tai useampi prosessi kirjoittaa yhtäaikaisesti tiedostoon, tulee vastaan ilman tiedostolukkoja mitä mielenkiintoisimpia tapahtumia.
Mee kirjoitti:
// Write the new data back to our file $handle = fopen($file, 'w'); fwrite($handle, serialize($online)); fclose($handle); flock($file); ?>Tämän pitäisi toimia.
Mitäs tässä nyt niinku käytännössä tapahtuu kun tiedosto vain lukitaan noin hassun yksinkertaisesti, pystyykö tuota lukeen tai kirjoittaan tavallisesta vai mitä ihmettä?
Mee kirjoitti:
// Write the new data back to our file $handle = fopen($file, 'w'); fwrite($handle, serialize($online)); fclose($handle); flock($file); ?>Tämän pitäisi toimia.
Ei toiminut.. Virheilmoitus:
Warning: Wrong parameter count for flock() in /var/www/virtual/......../online/online.php on line 50
CatZ kirjoitti:
Mee kirjoitti:
// Write the new data back to our file $handle = fopen($file, 'w'); fwrite($handle, serialize($online)); fclose($handle); flock($file); ?>Tämän pitäisi toimia.
Ei toiminut.. Virheilmoitus:
Warning: Wrong parameter count for flock() in /var/www/virtual/......../online/online.php on line 50
Tuon pitäisi olla joku tämänlainen:
flock($handle, 2);
Mutta joko tuo 2 on väärä tai jotain. Minäkin olen ymmälläni.
Ja php.net -sivua lainatakseni:
Tämäntapaiseen käyttöön suosittelisin oikean tietokannan käyttöä, jolloin kokonaista sisältöä ei korvata, vaan "sisältöä" lisätään rivi/rivejä kerrallaan.
Lopputuloskin on paljon luotettavampi.
Piittaakohan tuo file_get_contents lainkaan tuosta tiedostolukosta. Ja jos skripti kirjoittaa tiedoston uusiksi jokaisella suorituskerralla niin lukitushan täytyy tehdä skriptin alussa ja vapauttaa vasta sen lopussa. Ja täytyyhän siihenkin jollain tavalla reagoida jos tiedostoa yrittää lukea ja se onkin lukittu.
tiedostolukko estää lukemisen (näin määriteltynä) vain levyjärjestelmässä, eli file_get_contents('tiedosto.txt'); ei lue tiedostoa ennen lukon aukeamista, file_get_contents('http://www.foo.bar.invalid/tiedosto.txt'); taas lukee.
Aihe on jo aika vanha, joten et voi enää vastata siihen.