16

Currently I have a file called "hits.php" and on any page I want to track page hits I just use <?php include("hits.php"); ?>

How can I track unique visitors only though? My hits are false since it can be refreshed by the same person and hits go up.

Here's my source:

<?php
 $hits = file_get_contents("./client/hits.txt"); 
 $hits = $hits + 1; 

 $handle = fopen("./client/hits.txt", "w"); 
 fwrite($handle, $hits); 
 fclose($handle); 

 print $hits; 

?>

I don't really know how I could do cookie checking... is there a way to check IP's? Or what can I do?

Thanks StackO.

Kyle
  • 3,004
  • 15
  • 52
  • 79
  • 2
    I would highly consider using something other than a flat file to keep track of the number of hits a script has. The reason being is that a race condition can occur and it'll either skip counting a few entries or (worse yet) fail to open the file and reset the count back to 1 (if file_get_contents() returns FALSE, FALSE + 1 = 1). – Mr. Llama Oct 23 '10 at 05:20

7 Answers7

19

The simplest method would be cookie checking.

A better way would be to create an SQL database and assign the IP address as the primary key. Then whenever a user visits, you would insert that IP into the database.

  1. Create a function included on all pages that checks for $_SESSION['logged'] which you can assign whatever 'flag' you want.
  2. If $_SESSION['logged'] returns 'false' then insert their IP address into the MySQL database.
  3. Set $_SESSION['logged'] to 'true' so you don't waste resources logging the IP multiple times.

Note: When creating the MySQL table, assign the IP address' field as the key.

<?php 
  session_start();
  if (!$_SESSION['status']) {
    $connection = mysql_connect("localhost", "user", "password");
    mysql_select_db("ip_log", $connection);

    $ip = $_SERVER['REMOTE_ADDR'];
    mysql_query("INSERT INTO `database`.`table` (IP) VALUES ('$ip')");

    mysql_close($connection);
    $_SESSION['status'] = true;
  }
?>
  • I don't know how to do cookie checking. How can I use cookies? – Kyle Oct 23 '10 at 01:15
  • Read my answer fully, you can also check IPs. On second thought, let me add something to it. –  Oct 23 '10 at 01:16
  • @Kyle: That's a completely different question, and one that can be answered by googling for [php cookies](http://www.google.com.au/search?sourceid=chrome&ie=UTF-8&q=php+cookies). – Marcelo Cantos Oct 23 '10 at 01:16
  • 1
    I learned about sessions and cookies from [Practical PHP Programming](http://www.tuxradar.com/practicalphp/10/0/0). Very clear, practical and thorough. (And I'd use sessions instead of regular cookies.) – William Linton Oct 23 '10 at 01:20
  • @Kyle, @willell I updated it to include a possible way to doing it. –  Oct 23 '10 at 01:26
  • Make sure you create your MySQL database with the IP address as the unique key. –  Oct 23 '10 at 01:28
  • Please check - I think this line: $_SESSION['status'] == true; should only have 1 '=' ??? – Simon Jan 29 '11 at 10:56
  • @Simon Thanks for catching that. I just cobbled this together in a few minutes so yeah... –  Jan 29 '11 at 13:52
  • @GlennNelson and what if i want that cookie be expired after 2 hours so that if the same visitor came back again after 2 hours will be counted as well again. ~ thanks – Reham Fahmy Dec 31 '12 at 17:47
  • @JackBen I'm not sure at what point exactly a session would expire with PHP, but you could put some form of timestamp on each page hit and check it has been at least 2 hours before logging another visit. This method doesn't explicitly use cookies, although PHP does generate a session cookie itself for identification. –  Dec 31 '12 at 20:03
  • @GlennNelson i've very thinkable problem :( suppose i'm gonna get 1 point for every unique visitor visit certain link ... and if that visitor visit the same link after 12 hours will be also counted and get one more point. but if that visitor came back in less than 12 hours will not be counted so give me notes just best way to do it without hurting my hosting resources since i may get 10K visitors per day ~ thanks a lot – Reham Fahmy Dec 31 '12 at 22:13
  • @JackBen It's really better to ask this as another question. The comments isn't the place for this. –  Jan 01 '13 at 00:50
  • 3
    what about multiple visitors from the same ip address? For example there are thousands of students in a university using the same wifi. – Elyor Aug 31 '15 at 14:22
  • Just use cookie and check if cookie is set, if yes, enough, its not a new visitor, if no, the set cookie and add to database of hits. – Asuquo12 Apr 07 '21 at 15:41
4

There isn't a perfect solution, but the first two methods (IP address and/or cookies) are the most reliable, and a combination might be even better.

Rather than reinventing the wheel I used an off the shelf solution. For commercial reasons I avoided Google Analytics (I don't want Google to know my web stats - their best interests are not mine). They're probably fine for non-commercial websites, or if you don't use Google for advertising. There are also dozens of alternatives. Eg I use Getclicky.com

winwaed
  • 7,645
  • 6
  • 36
  • 81
3
  1. At a basic level, you can get the client's IP address by using the PHP $_SERVER['REMOTE_ADDR'] property
  2. Consider setting a cookie or using a session, though this can be defeated by deletion of a cookie or cookie rejection. See the PHP setcookie docs for more info.
  3. There are other methods for browser fingerprinting - check out all the different data you could conceivably use at https://coveryourtracks.eff.org/
Fanky
  • 1,673
  • 1
  • 18
  • 20
JAL
  • 21,295
  • 1
  • 48
  • 66
2

I found the solution of very poor quality and just a quick and dirty way of doing it.

I too was developing something similar and formulated a quick method which works without redundancy.

I needed a counter for every time someone accessed another user's profile.

Pseudo:

  • Create a table with viewer's name and viewee's name (daily_views table).
  • Check to see if exists the viewer's name with the viewee's name (on the same row).
  • If they do not exist, update user counter +1 (in users table).
  • Else do nothing.
  • Reset entire table values null every 24/12 hours via cron job.

This will deny the same person accessing the same user profile to add 1 to the counter on refresh for the whole day (or 12 hours) whereas the above solution by Glenn Nelson would indeed add 1 to the counter, but deny adding to every user's counter at the same time.

Not only this, but if you were to logoff and log back in to the website, then it would simply re-add to the counter in which some cases trolls and haxorz wannabe's will exploit this (as the session is destroyed and started again).

Here are my sample tables:

users 
{
user_id INT(8) auto increment, user_name varchar(32), user_counter INT(12)
};
daily_views
{
view_id INT(8) auto increment, viewer_name VARCHAR(32), viewee_name VARCHAR(32)
};

Here is sample code I've written:

<?php
session_start();
$uname = $_SESSION['username'];
$vieweepage = $_GET['name']; //gets the name of the persons page/profile via previous page/form
$connect = mysql_connect("localhost","user","password") or die("Couldn't connect; check your mysql_connect() settings");
$database = mysql_select_db("database") or die("Could not locate database!");

$query = mysql_query("SELECT user_counter from users");
$query = mysql_fetch_row($query);
$counter = $query[0];
$viewcheck = mysql_query("SELECT viewer_name from daily_views WHERE viewee_name='$vieweepage'");
$viewrow = mysql_num_rows($viewcheck);

$newcounter = $counter + 1;

if($viewrow == 0)
{
$update = mysql_query("UPDATE users SET user_counter='$newcounter' WHERE user_name='$vieweepage'");
$insert = mysql_query("INSERT into daily_views (viewer_name, viewee_name) VALUES ('$uname', '$vieweepage')");
}
?>
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Sam G
  • 31
  • 6
2

How about google analytics if you cant. you could do a database or create another file with the IPs in it, but it could get complicated with a flat file like that.

Matt
  • 7,049
  • 7
  • 50
  • 77
0

currently i am using remote address and session ID for visitor.i think its valid visitor because a single user can visit no of times in a days and counter not depends on refresh its only depends on new session.

Saurabh Chandra Patel
  • 12,712
  • 6
  • 88
  • 78
0

You could save a timestamp to localStoage in javascript. LocalStoage isn't removed by the browser, so you should be save to check against that. I know that it isn't serverside checking, but it may be helpful anyway.

Sebastian Td
  • 174
  • 1
  • 7