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.
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