View previous topic :: View next topic |
Author |
Message |
kev1952 -
Joined: 08 Sep 2005 Posts: 105 Location: Townsville Australia
|
Posted: Mon Dec 26, 2005 1:18 pm Post subject: Hit Counter |
|
|
I use this script I wrote to process the Abyss log to get the number of unique hits on my site:
Code: | <?php
// *** Start Remote Authority Check ***
$myip = "127.0.0.1";
$ra = $_SERVER["REMOTE_ADDR"];
if ($ra <> $myip) {
return;
}
// *** End Remote Authority Check ***
// Start Display
echo "<center><h3>Stats</h3></center>";
$log_path='..\log\access.log'; // Alter if different
$ct = date("d/M/Y H:i:s");
// Fetch start date and time
$text = fopen($log_path,'r') ;
$txt = fgets($text);
$first = strpos($txt,'[')+1;
$last = strpos($txt,'+')-$first;
$st = substr($txt,$first,$last);
$da = substr($st,0,11);
$ti = substr($st,12,8);
$dt = "$da $ti";
fclose($text);
// Define Variables (not strictly needed but prevents warnings)
$c = 0;
$f = 0;
$chk = 0;
$txt = 0; // Reset from first use
// Process log file
$txt = fopen($log_path,'r') ;
if ($txt) {
while (!feof($txt)) {
$buffer = fgets($txt);
$string = substr($buffer,0,15);
if ($f <> 0) { $chk = $f; }
$f = rtrim($string," -");
if ($f != $chk and $chk <> 0) {$c++; }
}
fclose($txt);
}
if ($dt == 0) {$dt = $ct; }
echo "<center><b>Current Time $ct</b></center><br>";
echo "<center><b>Hits from $dt = $c</b></center><br>";
?> |
It is designed to only display locally (hence the $_SERVER check) and it works pretty well. It performs a simple line by line read of the log and increments a counter each time it reads a new ip address. This is good but it falls down when there is more than one user online at the same time. It doesn't stop working but it does increment the counter for the same user twice (or more) because of the fact that it reads the log sequentially.
I want to be able to perform another check to see if the current IP is the same as one previously used elsewhere (non sequentially) in the log. I imagine I would need to use some kind of array to achieve this but am having great difficulty getting my head around "array" variables. Last time I used arrays was in BASIC many years ago.
Sorry about this being a bit long winded but I needed to explain the problem properly. Anyone have any ideas how to improve it and how to solve the problem I am faced with? The stats I get from it are only for my own info and not displayed to users online. _________________ Cheers.... Kev
Kev's Place - http://www.kevsplace.com
Powered by Abyss X1. |
|
Back to top |
|
 |
MonkeyNation -
Joined: 05 Feb 2005 Posts: 921 Location: Cardiff
|
Posted: Mon Dec 26, 2005 2:56 pm Post subject: |
|
|
I'm not totally sure what you're asking. But this is an example of a hit counter with a few options I made quickly.
Code: | <?php
function logvisit($input) {
global $ct,$log_path;
$records = explode("\n", $input);
foreach($records as $this_record) {
if ($this_record == "")
continue;
$record_data = explode(";", $this_record);
if ($record_data[0] == $_SERVER['REMOTE_ADDR']) {
$result .= $record_data[0].";".$ct.";".($record_data[2]+1)."\n";
$counted = true;
} else
$result .= $record_data[0].";".$record_data[1].";".$record_data[2]."\n";
}
if ($counted != true)
$result .= $_SERVER['REMOTE_ADDR'].";".$ct.";1\n";
return $result;
}
function hitcount() {
global $log_path,$ct;
$cache = implode("", @file($log_path));
if (!$handle = fopen($log_path,'w+'))
return false;
if (!fwrite($handle, logvisit($cache)))
return false;
fclose($handle);
return true;
}
function hits($type) {
global $log_path;
$file = @implode("", @file($log_path));
$file = explode("\n", $file);
foreach($file as $this_line) {
$this_line = explode(";", $this_line);
$total += $this_line[2];
if ($max['hits'] < $this_line[2]) {
$max['ip'] = $this_line[0];
$max['hits'] = $this_line[2];
}
}
if ($type == "max")
return $max;
elseif ($type == "total")
return $total;
}
function listhits() {
global $log_path;
$file = @implode("", @file($log_path));
$file = explode("\n", $file);
foreach($file as $this_line) {
$this_line = explode(";", $this_line);
if ($this_line[0] != "")
echo "<center><b>".$this_line[0]." has visited ".$this_line[2]." times. Last visit: ".$this_line[1].".</b></center><br>\n";
}
}
/*
* Things to configure, etc:
*
* Functions:
* logvisit - Internal function for use with hitcount().
* hitcount - Count another hit, and increment if IP exists.
* hits - Specify max, or total as 1st paramater to retrieve max or total hits. Max returns an array with two properties: ip and hits.
* listhits - Outputs a list of every logged hit.
*/
$makevisible = array("127.0.0.1", "192.168.1.1", "10.0.0.1"); // Show statistics to these IPs. Comment out to show to all.
$log_path='access.log';
$ct = date("d/M/Y H:i:s");
//Count another hit
hitcount();
//Show statistics
if (!is_array($makevisible) || in_array($_SERVER['REMOTE_ADDR'], $makevisible)) {
echo "Total hits: ".hits("total")."<br>\n";
$max = hits("max");
echo "Most user visits: ".$max['ip']." with ".$max['hits']." hits.<br>\n";
echo "<h3 style='text-align: center; text-decoration: underline;'>In depth</h3>\n";
listhits();
}
?> |
Needlessly complicated/long? Yes.
The point? Demonstration.
Also, most likely full of bugs etc, only a quick example. _________________
 |
|
Back to top |
 |
 |
kev1952 -
Joined: 08 Sep 2005 Posts: 105 Location: Townsville Australia
|
Posted: Mon Dec 26, 2005 4:05 pm Post subject: |
|
|
I appreciate the trouble you went to with this but most of it is way over my head.:(
All I want to end up with is the total number of unique hits. I did run the script you made and it worked sort of. As you said, there are a number of errors in it and the output is way too much detail.
My own script gets me almost there except for the duplication of ip's that happens. All I now want it to do is maintain a list of ip's that have already been processed and screen them out so that if the ip is already present (and counted) in the log then ignore any further instances of that ip (even if the ip concerned is not in sequential order in the log).
Am I making sense? _________________ Cheers.... Kev
Kev's Place - http://www.kevsplace.com
Powered by Abyss X1. |
|
Back to top |
|
 |
MonkeyNation -
Joined: 05 Feb 2005 Posts: 921 Location: Cardiff
|
Posted: Mon Dec 26, 2005 7:52 pm Post subject: |
|
|
Ah, I think understand you now.
Code: | <?php
function isunique($data) {
global $ip_log_path;
$data = explode("\n", $data);
foreach($data as $this_line) {
if ($this_line == $_SERVER['REMOTE_ADDR'])
return false;
}
return true;
}
function hitcount() {
global $ip_log_path,$total_log_path;
$cache = @implode("", @file($total_log_path));
$cache2 = @implode("", @file($ip_log_path));
if (!isunique($cache2))
return false;
if (!$handle = fopen($total_log_path,'w+'))
return false;
if (!$handle2 = fopen($ip_log_path,'w+'))
return false;
if (!fwrite($handle, $cache+1))
return false;
if (!fwrite($handle2, $cache2."\n".$_SERVER['REMOTE_ADDR']))
return false;
fclose($handle);
fclose($handle2);
return true;
}
function totalhits() {
global $total_log_path;
return (int)@implode("", @file($total_log_path));
}
/*
* Configuration / function calls
*/
$ip_log_path = "visitbyips.log";
$total_log_path = "visit.log";
hitcount(); // Will increment the counts if nececary.
echo totalhits(); // Will say how many unique hits have been to date.
?> |
This will create two files (visit.log and visitbyips.log (Can shange if you like.)) which will calculate how many unique hits the page sees.
If it seems complex, basically, as long as you include the code before the /* */ bit, you can just use hitcount() and totalhits() to operate it, providing you set the two variables for the log names.
I didn't spend all that long on the other one, but out of interest, what were the errors? _________________
 |
|
Back to top |
 |
 |
kev1952 -
Joined: 08 Sep 2005 Posts: 105 Location: Townsville Australia
|
Posted: Thu Dec 29, 2005 6:59 am Post subject: |
|
|
Firstly, please accept my apology for being so long getting back to you on this. I've had a "stuff the computer" type week. :(
The code above may be just what I wanted. I take it that it is designed to run as a real-time count instead of using the abyss.log file? I'll integrate it in the index page and let you know in a week or so how it's going. I gave it a quick experimental run and it seems to be all okay.
Your other script had some "undefined variable" errors and didn't increment the actual hits. It showed the unique addresses okay but came back with a zero result for the hits by each IP. I didn't spend much time de-bugging as it really wasn't quite what I had in mind.
Thanks again for your assistance, MN! _________________ Cheers.... Kev
Kev's Place - http://www.kevsplace.com
Powered by Abyss X1. |
|
Back to top |
|
 |
MonkeyNation -
Joined: 05 Feb 2005 Posts: 921 Location: Cardiff
|
Posted: Thu Dec 29, 2005 1:27 pm Post subject: |
|
|
kev1952 wrote: | Your other script had some "undefined variable" errors and didn't increment the actual hits. It showed the unique addresses okay but came back with a zero result for the hits by each IP. I didn't spend much time de-bugging as it really wasn't quite what I had in mind. |
It will give a warning the first time (Forgot an @ there), but other than that, I can't see what could go wrong. Could just be incompatability with PHP5 or something. _________________
 |
|
Back to top |
 |
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|