HStats - Counting and Statistics for PHP

A pragmatic and useful file based visit counter and page viewing statistics module for PHP5.

I've had a lot frustration finding a good counting and statistics component for PHP. Most solut­ions I tried needed MySQL, while one of the requirements for C­MME is not to be dependent of a database. All solutions I tried didn't have a functional interface. They were script based. So all of them needed to be included in pages and were driven by setting global constants and variables. Most of the solutions I tried, just didn't work, reworking them to e.g. the fSQL flat file database library also didn't work. So after 5 evenings (and part of the nights) of searching for an 'of the shelf' solution, I decided that I'd better create a counting and statistics component myself. It took me only 2 hours to setup the counting mechanism itself and only one evening to create the (be it simple) reporting engine. I should never have even tried to search for an existing one! What a frustration.

 

A small example

­
Figure 1: Example of using hstats
 
 
require_once('hstats/hstats.php');
 
 
 
function count_page($pagename) {
 
    $hstat_obj=new hstats('./counts');
 
    $count=$hstat_obj->count($pagename);
 
    return $count;
 
}
 
 
 
function output_count($pagename) {
 
    $hstat_obj=new hstats('.counts');
 
    return $hstat_obj->get_count($pagename);
 
}
 
 

Just require hstats in your code, create a new hstats object with a directory where hstats can create directories and create files and start counting page visits. That's all there is to it.  You can see a code sample in figure 1.

The count() function returns the total count for a page. This can be used in your HTML to display the visit count of page. There's also a function get_count(), which doesn't count, but only returns the latest count.

Workings

Hstat creates count files for years on a per page basis. It uses a directory per year and it counts for months and weeks. It doesn't count on a per day basis, to keep the counting files small.

While it counts pages, it also counts a total for all counted pages, which is stored in the file 'hstat_totals_php'.

By default hstats keeps an administration for each visitor on your site, of the last visited pages. It does this in a session variable. By default it counts page visits only every two minutes. This number can be changed using the global variable $HSTATS_COUNT_TIME. Setting this global variable to a different number configures hstats to use a different timeout value for counting. E.g., setting it to 0 will count all page requests (so if the user presses 'refresh' often, all refreshes will get counted).

Again, the granularity of counting is weeks, furthermore, it counts browsers, operating systems and countries (from the 'supported' accepted languages string of your browser).

Other global variables: $HSTAT_CHART_WIDTH, $HSTAT_CHART_HEIGHT. These variables default to 750px and 325px respectively. Set them to different values to get differently sized charts.

To get the browser, hstats depends on a local variant of the get_browser() PHP call. It is a modified variant of PHP standalone get_browser() for Browscap, written by Alexandre Alapetite, license: BY-SA.

Reporting­

Reporting
 
 
 
   $hstat_obj=new hstats("./counts");
 
   echo $hstat_obj->markup("index.php");
 
 

Hstats can report the totals over all years; totals per page for one year, totals for all pages for one year and totals per page and for all pages per month. Hstats reports on visits, operating system, browser and countries.

The markup function depends on the $_REQUEST variable to know what to do. The following parameters are used:

  • action is used for the type of report. Values: hstat_year, hstat_month and hstat_allyears.
  • page (optional) is used for the page to report on.
  • year (numerical) (only relevant for hstat_year and hstat_month) is used for the year to report on.
  • month (numerical) (only relevant for hstat_month) is used for the month to report on.

hstat_allyears makes the markup() function return a report about visits on all years and all pages. This reports about the total number of visits over all years per month, browser, operating system and country.

hstat_year make the markup() function report vists on a given year, for a given page (if set). This reports about the total number of visits over one year per month, browser, operating system and country.

hstat_month makes the markup() function return a report about visits for a given month in a given year, for a given page (if set). This reports about the total number of visits over one year in one month, browser, operating system and country.

The markup() function needs a scriptname as an argument. The HTML it returns contains links that include this scriptname. A report for a year links to months and vise versa. A sample script for using  hstats to report on page visits is given below.

Reporting with hstats
<?php
########################################################################################
# CMME - Content Management Made Easy, (c) 2007-2008, Hans Oesterholt, License: Creative Commons BY-SA
########################################################################################
require_once('hstats/hstats.php');
require_once('cms.php');
 
####################################################################################
# Configuration
####################################################################################
 
$config=new config();
setLang($config);
 
$env=$config->environment();
$env=$config->sanitizeEnv($env);
if ($env=="%wrong%") {
	echo "<div class=\"error\">".translate("Not an allowed environment")."</div>";
	exit(1);
}
 
if (isset($_REQUEST['page'])) { $pgref="&page=".$_REQUEST['page'];$page=$_REQUEST['page']; }
else { $pgref=""; $page="home"; }
//$pgref=$config->sanitizePage($pgref); This doesn't work, but also isn't necessary . Validating page is enough (see code above here).
$page=$config->sanitizePage($page);
if ($page=="%wrong%") { # || $pgref=="%wrong%") {
	echo "<div class=\"error\">".translate("Not an allowed page")."</div>";
	exit(1);
}
 
if (isset($_REQUEST['year'])) { $year=$_REQUEST['year']; }
else { $year=date('Y'); }
$year=$config->sanitizeYear($year);
if ($year=="%wrong%") { 
	echo "<div class=\"error\">".translate("Not an allowed date/year")."</div>";
	exit(1);
}
 
if (isset($_REQUEST['month'])) { 
	$m=$config->sanitizeMonth($_REQUEST['month']);
	if ($m=="%wrong%") {
		echo "<div class=\"error\">".translate("Not an allowed date/month")."</div>";
		exit(1);
	}
}
 
####################################################################################
# Statistics 
####################################################################################
 
$stats=new hstats($config->anyDir('counters'),$config->anyHtml('counters'));
 
####################################################################################
# Output
####################################################################################
 
$config->output("<div class=\"statistics\">");
 
$config->output("<div class=\"menu\">");
$config->output("<a class=\"entry\" href=\"".
				$config->script("index.php")."?env=$env$pgref\" >".
				translate("To %1",$page).
				"</a>"
				);
$config->output("&nbsp;&nbsp;");
$config->output("<a class=\"entry\" href=\"".
				$config->script("statistics.php")."?action=hstat_allyears&env=$env\" >".
				translate("All years for all pages").
				"</a>"
				);
$config->output("&nbsp;&nbsp;");
$config->output("<a class=\"entry\" href=\"".
				$config->script("statistics.php")."?action=hstat_year&year=$year&env=$env\" >".
				translate("Year %1 for all pages",$year).
				"</a>"
				);
$config->output("</div>");
 
$config->output("<hr />");
 
$config->output($stats->markup($config->script('statistics.php')));
 
$config->output("</div>");
echo $config->html($config->headers().$config->body($config->output()));
 
?>

License

HSTATS - A visitors counting and statistics library
Version v1.05
Copyright (c) 2007-2008 Hans Oesterholt
License: Creative Commons BY-SA



Visited: 1132