Licznik pobierań - zerowanie wyników!

0

Witam.
Na mojej stronie internetowej od dłuższego czasu używam skryptu PHP, który ma za zadanie pokazać ile razy ściągnięto jakiś plik z serwera.

Nazywa sie u mnie download.php i wygloda tak:

<?
$filename = 'counter_' . $_GET['file'] . '.txt';

  if (file_exists($filename))
    {
     $fp = fopen($filename, 'r');
     $count = fgets($fp, 4096);
     $count += 1;
           fclose($fp);

     $fp = fopen($filename, 'w');
           flock($fp, LOCK_EX);
           fputs($fp, $count);
           flock($fp, LOCK_UN);
           fclose($fp);
    }
header ('Location: http://adresmojejstrony/projekty/' . $_GET['file']);
?>

Dla każdego pliku, który udostępniony jest do ściągnięcia tworzony jest plik tekstowy, ktorego nazwa jest skladową wyrazu "counter_" oraz samej nazwy ściąganego pliku.

Skrypt wywołuję poleceniem (w sekcji BODY strony download.html):

<?
   function GetCount($file)
   {
      $filename = "counter_$file.txt";

      if (file_exists($filename))
        {
         $fp = fopen($filename, 'r');
         $count = fgets($fp, 4096);
         fclose($fp);
         return $count;
        }
     else
        {
        $nie = '0';
        return $nie;
        }
   }
?>

Wynik wyświetlam w taki sposób:

<font size="1">Plik pobrano: <? echo GetCount("nazwaplikuscioganego.zip"); ?> razy</span>

Czyli plik taki a taki pobrano n razy.

Wszystko jest OK, ale co jakis czas pliki tekstowe zerują się! Dlaczego? Jak temu zapobiec? Czy jest możliwe, że np. z powodu nieodpowiedzi serwera plik jest zerowany? Prosze o przeanalizowanie tego przykładu i jakieś podpowiedzi, jak zmodyfikować ten skrypt, aby nie działy sie takie cuda. Bo dochodzi do sytuacji, ze np. w poniedziałek mam 60 ściągnięć, a we wtorek nic!

Bardzo proszę o pomoc.
Pozdr
Pepe

Ps: aha, serwer to piwko.pl ( ;( ) , więc tylko php, żadne mysqele nie wchodzą w grę...

0

Być może to dla tego że przy odczycie nie blokujesz pliku a przy zapisie tak. Wtedy ktoś mógł pobrać wartość 60, zapisać 61, a drugi w tym samym czasie pobrał wartość 0 i zapisał 0. Ale przyznaje że bardziej zgaduje niż wiem.

pozdro

0

Hmm... Wszystko jest kwestią tego, że nie sprawdzasz, czy udało Ci się otworzyć plik do odczytu... Przez to jak Ci się nie uda, to licznik zostaje 0 i taki jest zapisany do pliku. Zrób tak: Jak Ci się uda otworzyć i przeczytać, to zapisz. A jak nie, to daruj sobie to jedno ściągnięcie i nie zapisuj, albo próbuj otworzyć, aż się uda (jest to troszkę niebezpieczne, bo przy zablokowaniu pliku nikt nie będzie mógł ściągnąć pliku). Możesz ew. próbować określoną ilość razy, a jak się nie uda, to sobie darujesz i nic nie zapisujesz w pliku. Mam nadzieję, że dało się zrozumieć :)

0

Hmm... Wszystko jest kwestią tego, że nie sprawdzasz, czy udało Ci się otworzyć plik do odczytu... Przez to jak Ci się nie uda, to licznik zostaje 0 i taki jest zapisany do pliku. Zrób tak: Jak Ci się uda otworzyć i przeczytać, to zapisz. A jak nie, to daruj sobie to jedno ściągnięcie i nie zapisuj, albo próbuj otworzyć, aż się uda (jest to troszkę niebezpieczne, bo przy zablokowaniu pliku nikt nie będzie mógł ściągnąć pliku). Możesz ew. próbować określoną ilość razy, a jak się nie uda, to sobie darujesz i nic nie zapisujesz w pliku. Mam nadzieję, że dało się zrozumieć :)

A moglby ktos napisac, jak wygloda tak funkcja, ktora sprawdza czy plik zostal otwarty? Nie znam PHP, dlatego pytam.
Pozdr

0

Hmm... Najprościej byłoby (nie pamiętam jak to się sprawdzało, czy plik się otworzył) przed odczytaniem licznika nadać mu jakąśujemną wartość (chociażby -1) i po próbie odczytania sprawdzić, ile licznik wynosi. Jeśli -1, to znaczy, że się nie otworzyło i nic nie robimy. Jeśli natomiast jest większe od -1, to dodajemy 1 do licznika i go zapisujemy.

0

chyba tak:

if(($fp = fopen($filename, 'w'))!==false){
 // plik otworzono
} else {
 // błąd otworzenia plika
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1