Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Licznik odwiedzin... problem...
Forum PHP.pl > Forum > PHP
*_ENIGMA
Witam!

Otórz mam na stronie licznik odwiedzin i już drugi raz sam się wyzerował (plik z liczb± odwiedzin stał się pusty) :-/

Podaję swój skrypt, bo ja już nie wiem gdzie leży przyczyna :-/
CHMOD mam ustawiony pliku z wpisami licznika (licznik.dat) na 777.

Plik licznik.php (inkludowany: @include("index/licznik.php"); )
  1. <?php
  2.  
  3. $plik = "index/licznik.dat";
  4. $waga = @filesize($plik);
  5.  
  6. $fop = @fopen("$plik", "r");
  7. @flock($fop, 1);
  8. $czytaj_l = @fread($fop, $waga);
  9. @flock($fop, 3);
  10. @fclose($fop);
  11.  
  12. $czytaj_l++;
  13.  
  14. $fop = @fopen("$plik", "w");
  15. @flock($fop, 2);
  16. @fwrite($fop, $czytaj_l);
  17. @flock($fop, 3);
  18. @fclose($fop);
  19.  
  20. echo("$czytaj_l");
  21.  
  22. ?>


Proszę o podpowiedzi jaka może być przyczyna samoistnego zerowania się tego licznika...
Najciekawsze jest to, że dałem blokadę flock() do zapisu i odczytu a i tak się wyzerował :-/

Pozdrawiam
Pigula
a sproboj tak:
  1. <?php
  2. $czytaj_l = @fread($fop, $waga+1);
  3. ?>

mi kiedys to pomoglo winksmiley.jpg

--------------
jak to nie pomoze to daj echo co jakis czas zeby zobaczyc co sie dzieje ze zmienna
*_ENIGMA
Cytat
mi kiedys to pomoglo


Znów dzi¶ mi się sam wyzerował licznik mimo, że zrobiłem jak mi tu poradzono :-(

Cytat
jak to nie pomoze to daj echo co jakis czas zeby zobaczyc co sie dzieje ze zmienna


Sprawdziłem i zmienne zachowuj± się w prawidłowy sposób....

Czy to nie może być skutkiem tego, że serwer robi automatycznie co jaki¶ czas backup? (dodam, że stronę mam na płatnym serwerze).

Dlaczego mimo zastosowania funkcji flock() ten problem występuje?
Szczerze mówi±c dziwne to wszystko, zwłaszcza że skrypt licznika jest tak banalny, że ciężko byłoby się w nim pomylić...

Pozdrawiam
Kocurro
Witam,

Samoistne generowanie sie licznika jest zwiazane z nastepujaca sytuacja:

Gdy zablokujesz za pomoca flock dostep do pliku najczesciej inna inwokacja skryptu nie moze odczytac jego wartosci, odczytuje wiec wartosc 0, ktora nastepnie inkrementuje. W tym samym czasie pierwsza inwokacja dokonuje zapisu i zdejkmuje blokade a druga inwokacja jest zablokowana z zapisem do chwili odblokowania zapisu.
Po odblokowaniu sie zapisu wpisuje wartosc jaka zna wiec 1 lub ciag pusty.

Ciag pusty dlatego, ze inkrementacja niczego daje w efekcie nic.

Proponuje na sam poczatek zdjecie malpek aby zobaczyc czy nie ma zadnych bledow. Po drugie proponuje linijke:

  1. <?php
  2. $czytaj_l++;
  3. ?>


zmienic na:

  1. <?php
  2. if(is_numeric($czytaj_l)){$czytaj_l++;}else{$czytaj_l=1;}
  3. ?>


Wten sposob jesli nastapi bledny odczyt wartosci licznika to zostanie wpisana 1 - wiec od zerowania bedzie dobrze zliczal. Jednak podejrzewam, ze chcesz unikanac zerowania. W tym celu mozna zrobic tak - jesli blednie odczyta to nie zapisywac. Oto kod po zmianach:

  1. <?php
  2. $plik = "index/licznik.dat";
  3. $waga = @filesize($plik);
  4.  
  5. $fop = @fopen("$plik", "r");
  6. @flock($fop, 1);
  7. $czytaj_l = @fread($fop, $waga);
  8. @flock($fop, 3);
  9. @fclose($fop);
  10.  
  11. if(is_numeric($czytaj_l)){
  12. $czytaj_l++;
  13.  
  14. $fop = @fopen("$plik", "w");
  15. @flock($fop, 2);
  16. @fwrite($fop, $czytaj_l);
  17. @flock($fop, 3);
  18. @fclose($fop);
  19.  
  20. echo("$czytaj_l");
  21. }
  22. ?>


Blad zerowania powstaje glownie wtedy gdy jedna inwokacja chce odczytac wartosc licznika podczas gdy druga zapisuje.

pozdr.
latet
Cytat(*_ENIGMA @ 2005-10-03 15:38:35)
Witam!
Otórz mam na stronie licznik odwiedzin i już drugi raz sam się wyzerował (plik z liczb± odwiedzin stał się pusty) :-/


Też tak miałem i zębami zgrzytałem. Ale doszedłem do przyczyny.
Winne jest otwieranie pliku w trybie "w". Zauważ, że zawarto¶ć pliku jest wtedy kasowana. Już wtedy, a więc jeszcze przed prób± założenia locka!

Ja doszedłem w końcu do tego co widać niżej. Zrób tak, a bedzie dobrze:

  1. <?php
  2.  
  3. $df="nazwaplikulicznika.txt";
  4. $krolicznika = 1; 
  5.  
  6.  
  7. if (file_exists($df))
  8. {  
  9.  
  10. if ($fp=@fopen($df, "r+")) // niedestrukcyjny tryb r+
  11. {
  12.  
  13. if( flock($fp, LOCK_EX)) // jesli sie uda sie zablokowac do zapisu
  14. {
  15. $count = intval(fgets($fp, 20)) + $krolicznika;  
  16. ftruncate($fp, 0); // wyczeszczenie zawartosci pliku
  17. fseek($fp, 0);  // pointer na poczatek pliku 
  18. fputs($fp, $count);  // zapis nowej liczby do licznika
  19. flock($fp, LOCK_UN);  // zdjecie blokady
  20. fclose($fp);
  21. echo $count;  // Wyswietlenie stanu licznika
  22. }
  23.  
  24.  else {
  25.  fclose($fp); // zamkniecie jesli nie mozna bylo zalozyc locka 
  26. }
  27.  
  28. }
  29.  
  30. else // jesli nie udało sie otworzyc pliku do zapisu (np. z powodu braku odp. uprawnien) 
  31. { echo "ERROR! Nie moge zapisywac do tego pliku!"; }
  32.  
  33. }
  34.  
  35.  
  36. else  // jesli plik $df licznika NIE istnieje - trzeba go stowrzyc
  37.  
  38. {  
  39.  
  40.  echo "Tworze nowy plik licznika. Prosze odwiezyc strone"; 
  41.  touch($df); // folder w ktorym ma powstac plik licznika musi miec atr. 777
  42.  chmod($df, 0666); // na wszelki wypdek
  43.  
  44. } 
  45.  
  46.  
  47. ?>


latet
To jest wersja lo-fi głównej zawarto¶ci. Aby zobaczyć pełn± wersję z większ± zawarto¶ci±, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.