0

I'm using the following basic PHP:

<?php

    if (file_exists('count_file.txt')) 
    {
        $fil = fopen('count_file.txt', r);
        $dat = fread($fil, filesize('count_file.txt')); 
        echo $dat+1;
        fclose($fil);
        $fil = fopen('count_file.txt', w);
        fwrite($fil, $dat+1);
    }

    else
    {
        $fil = fopen('count_file.txt', w);
        fwrite($fil, 1);
        echo '1';
        fclose($fil);
    }
?>

as a hit counter (I'd rather not have one but it's been insisted we do). The txt file keeps count of the hits and it works...however the counter randomly (sometimes after a few weeks, sometimes months later) decides to trip up and drops from say 4300 to 11. Can anyone tell me how to rectify this as it is becoming annoying??

John
  • 989
  • 2
  • 16
  • 29
  • Your hit counter is missing a file-lock. See `flock`. Otherwise you can easily have race-conditions if multiple scripts are opening and saving the file at once. [http://en.wikipedia.org/wiki/Atomicity_(database_systems)](http://en.wikipedia.org/wiki/Atomicity_(database_systems)) – hakre Jul 12 '12 at 12:21
  • could you elaborate please? I'm very new to PHP and this took me ages to get working – John Jul 12 '12 at 12:23
  • The PHP manual explains the `flock` function. On that page you will find user-comments explaining even further and presenting their stance how to write such a counter in a file. – hakre Jul 12 '12 at 12:24
  • I did look it up it just doesn't make sense to me currently - i.e i'm not sure how i implement it. – John Jul 12 '12 at 12:28
  • You might find it useful to read about File Locking first: http://en.wikipedia.org/wiki/File_locking – hakre Jul 12 '12 at 12:30
  • Thanks I understand the locking process now, just not how to implement flock into this piece of code – John Jul 12 '12 at 12:45
  • Okay, I suggest you grab yourself some non-technical book and a cup of hot tea first, step away from the computer for some time and then in a moment you won't expect it, it will become visible in your mind. – hakre Jul 12 '12 at 12:47

2 Answers2

1

You're not using any locking. If two or more requests hit your server at the same time, they're going to be stomping on each other's file operations. This sort of thing is better done in a database.

Marc B
  • 356,200
  • 43
  • 426
  • 500
1

The filesize function tells you the number of bytes in the file. PHP.net can describe how the function works to you. Instead of using that function you should read a line (fgets) from the file (that line should have the hit count on it) then you add one to the hit count and then re-save.

Let me give you an analogy. You are in the kitchen and you pull a container of blueberries out and you want to know how many blueberries there are but instead you ask the container how many inches long it is. Then you get rid of all the blueberries and put the number of inches + 1 blueberries in the container. Nothing about that makes any sense but that is what your script does. If you change the line that says: $dat = fread($fil, filesize('count_file.txt')); TO $dat = fgets($fil); You should be reading how many blueberries you have, adding one to that number and re-saving.

Ben Fischer
  • 6,382
  • 2
  • 17
  • 22
  • sorry this is over my head... – John Jul 12 '12 at 12:36
  • Ok, ignore what they are telling you about file locking. Based on your level of experience I doubt you are working with a site where this would even be important. See the edit to the answer for more details. – Ben Fischer Jul 12 '12 at 22:29