/* HIngo's Counter: hic.php */
$version = "0.91";
/* (c) Jan 2001 hingo@multi.fi
http://www.multi.fi/~hingo/hic/ */
/* Licensed for use under the GPL. See www.gnu.org for more info
http://www.gnu.org/copyleft/gpl.html */
/******************instructions****************************************
To use hic.php on your website, do the following steps
1) create an empty file
(say /home/user/public_html/logs/.htlog)
AND give it read and write permission
>chmod a+rw .htlog
>ls -las .ht*
3 -rw-rw-rw- 1 user gst 0 Jan 11 19:03 .htlog
2) create a file called .htaccess in your public_html directory
and add the following lines to it:
##############################################
#process all html-files with php
SetHandler application/x-httpd-php3
#don't show files beginning with ".ht"
Order allow,deny
Deny from all
##############################################
3) See the settings section below
4) copy this script to a file on your website.
(say /home/user/public_html/logs/hic.php)
5) access this script with your browser
(http://www.server.com/~user/logs/hic.php) to see that it works
and to get the last instruction. Which is...
6) When including your pages to be counted with the HIngo Counter use
at the end of your HTML-file.
*********************************************************************/
/****************** settings *****************************************/
//Specify which file we may use (must be world writable, chmod a+rw .htlog)
$logfile = "/home/username/public_html/logs/.htlog";
//You may specify a password needed to see the stats
$reqpasswd = "";
//If you're not interested in seeing what browser people use
//turn this to "no" to reduce the filesize of the log
$logagents = "no";
//This should be a directory where the script has write permission
$lockdir = '/tmp';
/*******************known bugs***************************************
1) Despite my best efforts, the locking mechanism still doesn't seem to work.
For some reason or another, the log will reset itself at random intervals.
Should fix it such that:
- The logging part writes in append mode a file similar to apache's logfile
- The analyzing/gouping/everything is done from this log when you ask to
view the stats.
This should be safer, since the file is never re-written, only appended. As
a bonus this will of course be more efficient (except for the rare occasions
when you are actually viewing the stats). Now that I think of it, why didn't
we do it like this in the first place?
***************************************************************************/
/********************begin script*************************************/
//Make a name for a file we will use as a lock.
//The intent is that this is somewhat unique
$lockfile = str_replace('/', '-', $logfile);
$lockfile = $lockdir . '/' . $lockfile . '.lock';
//Check if lock exists, and if it does, wait for half a second and try again
//Just in case something is wrong, if we've stopped for 2 seconds, just
//forget about counting and skip this
$stopper = 0;
while($stopper < 4){
if (file_exists($lockfile)) {
sleep(0.5);
$stopper++;
}else{
//Create a file that indicates a lock on the logfile
touch($lockfile);
//Now read the file, increment counters, and write back to it
if($fp = fopen($logfile, "r") ){
list($allstats, $setup) = unserialize(fread($fp, filesize($logfile)));
fclose($fp);
}
/* $allstats is an array of format
$allstats[$SCRIPT_NAME =>
"Hits" => $++,
"RemoteHost" => (name or ip => (hits=> $++, Agent => $agent ),
"Referer" => ($referer => $++)]
$setup contains additional info
$setup["StartDate" => unixtimestamp]
*/
//Set a start-date, if not set already
if(!$setup["StartDate"]>0){
$setup["StartDate"] = time();
}
//Increment counters. If the array didn't exist in the file
//(the file was empty) it seems to create itself now
$allstats[$SCRIPT_NAME]["hits"]++;
if($REMOTE_HOST){
$allstats[$SCRIPT_NAME]["RemoteHost"][$REMOTE_HOST]["hits"] =
$allstats[$SCRIPT_NAME]["RemoteHost"][$REMOTE_HOST]["hits"] + 1;
}else{
$allstats[$SCRIPT_NAME]["RemoteHost"][$REMOTE_ADDR]["hits"] =
$allstats[$SCRIPT_NAME]["RemoteHost"][$REMOTE_ADDR]["hits"] + 1;
}
if($HTTP_REFERER){
$allstats[$SCRIPT_NAME]["Referer"][$HTTP_REFERER] =
$allstats[$SCRIPT_NAME]["Referer"][$HTTP_REFERER] + 1;
}
if($HTTP_USER_AGENT && $logagents == "yes"){
if($REMOTE_HOST){
$allstats[$SCRIPT_NAME]["RemoteHost"][$REMOTE_HOST][$HTTP_USER_AGENT] =
$allstats[$SCRIPT_NAME]["RemoteHost"][$REMOTE_HOST][$HTTP_USER_AGENT] + 1;
}else{
$allstats[$SCRIPT_NAME]["RemoteHost"][$REMOTE_ADDR][$HTTP_USER_AGENT] =
$allstats[$SCRIPT_NAME]["RemoteHost"][$REMOTE_ADDR][$HTTP_USER_AGENT] + 1;
}
}
//write back to the file
$fp = fopen($logfile, "w");
fwrite($fp, serialize(array($allstats, $setup)));
fclose($fp);
//We're done, release the lock
unlink($lockfile);
//we're done. break out of the loop
$stopper = 100;
} //if/else
} //while
//The user is accessing this page:
//show statistics
if(basename($SCRIPT_NAME) == "hic.php"){
print "
HIngo's Counter: hic.php $version
";
if($reqpasswd != $passwd){
?>
HIngo's Counter use ";
print '
<?php include('.$SCRIPT_FILENAME.');?>
';
print "at the end of your HTML-file.
\n";
//Maintenance section*******************************
if(file_exists($lockfile)){
?> Note: When I just looked, it seems like the file where
our statistics are stored was locked. This probably means, that somebody
was being counted at that exact moment.
However, if the lock persists, it might also mean that something really
has locked up, and nothing is being counted anymore. If you wan't to force
the lock to be released, ">click
here.
Problem: Could not release the lock. For now, no visitors will be counted.
";
}
}
print "Homepage access statistics during ";
print date("Y-M-d", $setup["StartDate"])." to ".date("Y-M-d")."\n
\n";
//First we'll extract some info from $allstats
//Count hosts and agents
$agents = array();
$hosts = array();
$referers = array();
$refperpage = array();
reset($allstats);
//traverse through pages
while(list($key, $val) = each($allstats)){
$h = $val["RemoteHost"];
reset($h);
//traverse through remote hosts
while(list($k, $v) = each($h)){
//count the hits for RemoteHost
$hosts[$k] = $hosts[$k] + $v["hits"];
//traverse through the agents of this host
while(list($kk, $vv) = each($v)){
$agents[$kk] = $agents[$kk] + $vv;
}
}
//count the referers
//reset() would complain for a null-value, so we use if()
//with $agents it didn't matter, because they're togehter
//with the "hits" entry, that always exists
if($r = $val["Referer"]){
reset($r);
while(list($k, $v) = each($r)){
$referers[$k] = $referers[$k] + $v;
$refperpage[$key][$k] = $v;
}
}
}
//the "hits" entry is not an agent, but interesting to know
$allhits = $agents["hits"];
unset($agents["hits"]);
//Now it's time to tell the results
//Hits/page
//Function used to sort the $allstats-array
function allcmp($a, $b){
return $b["hits"]-$a["hits"];
}
uasort($allstats, "allcmp");
//Table with hits/file
print "\n";
print "| Page: | Hits: | Unique Hosts: |
\n";
reset($allstats);
while(list($key, $val) = each($allstats)){
$hits=$val["hits"];
$uniq = count($val["RemoteHost"]);
print "| $key | $hits | $uniq |
\n";
}
print "| ALL PAGES | $allhits | ";
print "".sizeof($hosts)." |
\n";
print "
\n";
//hits/hosts
arsort($hosts);
print "Hits from different hosts:
";
print "\n";
print "| Remote host address: | Visits: |
\n";
reset($hosts);
while( list($key, $val) = each($hosts) ){
print "| $key | $val |
\n";
}
print "
\n";
//hits/different referers
arsort($referers);
print "Referers (Where the people are coming from):
";
print "\n";
print "| Referer: | Hits: |
\n";
reset($referers);
while( list($key, $val) = each($referers) ){
print '| ' . chunk_split($key) . ' | ';
print "$val |
\n";
}
print "
\n";
//From where did they come to each page:
print "Referers/page (From where did they come to this page. Or how do they move on my page.)
";
print "\n";
print "| Page (Total hits): | Hits/ Referers: |
\n";
ksort($refperpage);
reset($refperpage);
while(list($key, $val) = each($refperpage)){
print '| ' . $key .
" (" . $allstats[$key]["hits"] . ") | \n";
$refs = $refperpage[$key];
arsort($refs);
reset($refs);
while(list($k, $v) = each($refs)){
print '- ' . $v . ': ' .
chunk_split($k) . "
\n";
}
print " |
\n";
}
print "
\n";
//hits/agents if agents are counted
if($agents){
arsort($agents);
print "Browser popularity contest
";
print "\n";
print "| Browser: | Visits: |
\n";
reset($agents);
while( list($key, $val) = each($agents) ){
print "| $key | $val |
\n";
}
print "
\n";
}
//Ok. Let's draw some pivot's
//function to easily dump the arrays (debugging)
/**********************************************************************/
function print_array($array) {
if(gettype($array)=="array") {
echo "";
while (list($index, $subarray) = each($array) ) {
echo "- $index
=> ";
print_array($subarray);
echo " ";
}
echo "
";
} else {
echo $array;
}
}// end of print_array()
/*********************************************************************/
// print_array($allstats);
// print_array($agents);
// print_array($hosts);
// print_array($referers);
// print_array($refperpage);
/********************************************************************/
print "