phphitcounter

PHP multiple clients accessing same file


I started playing with PHP, and saw this code snippet that is supposed to act a hit counter for a webpage:

/* counter */

//opens countlog.txt to read the number of hits
$datei = fopen("/countlog.txt","r");
$count = fgets($datei,1000);
fclose($datei);
$count=$count + 1 ;
echo "$count" ;
echo " hits" ;
echo "\n" ;

// opens countlog.txt to change new hit number
$datei = fopen("/countlog.txt","w");
fwrite($datei, $count);
fclose($datei);

Based on what I read, multiple requests can run simultaneously on the server. So there is chance that they access this file countlog.txt at the same time (correct?). If so, this code doesn't work for a busy website (correct?). How would one change this code to make it work for a busy website? Can you use locks in PHP that is shared between multiple request?

PS: The question is NOT about counters. Please avoid using SQL in the answer if possible.


Solution

  • You could use flock() to get an exclusive lock on a file, see http://php.net/manual/en/function.flock.php

    $fp = fopen("/tmp/lock.txt", "r+");
    
    if (flock($fp, LOCK_EX)) {
        $datei = fopen("/countlog.txt","r");
        $count = fgets($datei,1000);
    
        $count=$count + 1 ;
        echo "$count" ;
        echo " hits" ;
        echo "\n" ;
    
        ftruncate($fp, 0);
        fwrite($fp, $count);
        fflush($fp);
        flock($fp, LOCK_UN);
    } else {
        echo "Could not lock file!";
    }
    
    fclose($fp);
    

    Maybe you should build a loop that waits for a successfull lock using usleep() to avoid active waiting: http://php.net/manual/en/function.usleep.php