Going Retro With PHP – A Hits Counter Step By Step

It wasn’t all that long ago that the web was littered with little “number of visitor” indicators. The point of these was either to show how popular your site was, or more likely just because the site owner had no administrator level site statistics program running. Now most sites have a sophisticated statistics system or other means of counting visitors and these visible counters have become less popular. It will still be a good learning experience to try making a script for counting visitors from scratch.

A simple function to detect a valid page load might look like this

function log_page_load(){
    $invalid_list = '/(googlebot|crawler)/i'; //set a regular expression that detects invalid agents like googlebot
    if (preg_match($invalid_list, $_SERVER['HTTP_USER_AGENT'])){
    // it is a bot
    }else{
    // it is probably a browser
    }
}

As you can see we are erring on the side of caution, making browsers the default for most possible strings. That is because there are probably countless possible browsers now with cell phones and other devices included. There’s no easy way to tell bot from human computer user there may be no perfect method that is always right. There definitely are techniques that are pretty accurate compared to what I show above but they are beyond the scope of this article.

Once we have decided the request is a real pageview we can get on with the reading and saving of data.

$filename = "counterfile.dat";
if(file_exists ($counter_file)){
    $counter_file = fopen($filename, 'r+');
    $total_count = trim(fread($counter_file, filesize($filename)));
}else{
    $counter_file = fopen($filename, 'w');
    $total_count = 0;
}
//other code here
...
//save file
ftruncate($counter_file,0);
fwrite($counter_file, $total_count);
fclose($counter_file);

First we opened the file, but since it may not exist we check that, and create it if it doesn’t (opening with w will do that). Otherwise it should work fine to read it. To save it we erase it (ftruncate($counter_file,0)) and write new data, which is just a number. In the next example let’s combine all that we have covered.

function log_page_load(){
    $filename = "counterfile.dat";
    if(file_exists ($counter_file)){
        $counter_file = fopen($filename, 'r+');
        $total_count = trim(fread($counter_file, filesize($filename)));
    }else{
        $counter_file = fopen($filename, 'w');
        $total_count = 0;
    }
    $invalid_list = '/(googlebot|crawler)/i'; //set a regular expression that detects invalid agents like googlebot
    if (!preg_match($invalid_list, $_SERVER['HTTP_USER_AGENT'])){
        //it is a brower. probably. increment and save.
        $total_count++;
        ftruncate($counter_file,0);
        fwrite($counter_file, $total_count);
    }
    fclose($counter_file);
    if(!trim($total_count))
        $total_count = 0; //let's make sure it is a 0 if it somehow was set to a blank string
    return $total_count;
}
echo "val= ". log_page_load(); //each load you get 1, 2, 3, 4

so there you have it, define the function and either capture the return value for later or print it as shown.
Isn’t there something missing though? Most of the counters are graphical since they are used on sites that have no scripting. How can we get graphics instead of just numbers as a text string? There are many ways, but try this on for size.

$page_loads = log_page_load(); //logs once and also return the new value
$page_l_str = strval($page_loads);
$icons = "";
for($i = 0; $i < strval($page_l_str); $i++){
    $icons .= '<imr src="images/' . $page_l_str[$i] . '.gif" />';
}
echo $icons;

that will produce image tags with the pattern <imr src=”images/1.gif” /> and so on. $page_l_str[$i] means get the letter with index $i.
Of course you might also wish to zero padd it or instead of images use <li>$page_l_str[$i]</li>, there are a limitless variety of possibilities with modern css and php.

To take this a step further you might want to build in counting of visitors instead on top of pageviews. That would be done by recording $_SERVER[‘REMOTE_ADDR’] and checking if the visitor has been there recently. You could use 2 counters for hits and unique hits, or some other combination. That’s all I will cover here though so that concludes the article on hit counters, I hope it has been informative.