php counter for web pages
Posted by jill (jill), 13 February 2003We need a php script to count hits on web pages. There are loads of free ones, can anyone recommend one? Also are there likely to be any security issues in using it/them?
Posted by admin (Graham Ellis), 13 February 2003Do you simply want to count your visitors, or count and log them? Do you want to tell your visitors their number, or be secretive about what your doing? Do you want to be able to count in an ordinary HTML page, or can the page counted by PHP? Do I ask far too many questions??
I've put together a little demo (there are lots of free counters because it's very easy to do) that does the whole thing on your site, under your control. I know you know some PHP, and having it under your control means that you can look after your own security issues.
Firstly, here's a page of plain old HTML, but it calls up an image that looks - well - a bit odd:
The Image is actually a piece of PHP which returns an image to the browser when it's loaded. Here's the file click.php4:
And the result is an image with a changing number written over it, and records written to a log file too so that you know something about your visitors.
I have put the live code at
and you can see the log file if you want at
and the counter record file at
You ask about security. The counter files should really be in a different directory that can't be see from the web - I've just got them where they are for you to see how they work ...
P.S. Counters are notoriously unreliable at telling you how many visitors you really have to an HTML page ... some visitors won't be notified to you at all as they're getting their stuff from a cache, and other will be counted more than once as they refresh ...
Posted by jill (jill), 14 February 2003Thanks for your very prompt reply - but it has prompted more questions! First, to answer yours:
We do want to count and log the visitors, and we do not require them to see the result.
The pages we are counting do not get cached, we have <meta http-equiv="pragma" content="no-cache"> etc in our template, so every hit will be counted. We do not need to count in an html page, we just need to be able to get the log and the results. And no, you do not ask too many questions, unless I do.
Unfortunately, although the code appears relatively short I don't completely understand it. Sorry. I can understand the bit where it adds one to the counter, and the bit where it puts the 'referer' into the log, but not the image bit really. If you did not want an image in the demopic page, how would you get the script to run?. Also presumably if you were counting hits on lots of pages you would need a mechanism - I suppose you could just do the log file, then get that into excel and do totals or something, or else have lots of separate counter.num files, perhaps called by the name of the 'referer'.
When I tested it on your site, I found that in I.E. every time I hit refresh the counter was incremented, but in Netscape 4 this did not happen - do you know why? Also I looked up HTTP_REFERER in php.net and found this:
'The address of the page (if any) which referred the user agent to the current page. This is set by the user agent. Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted.'
Is this why it does not work in Netscape 4?
Finally I loaded demopic.html, click.php onto our server and created two empty files counter.num and counter.demo with permissions 666, in a folder with write permissions as well, and I could not get it to work, or even show the image in the page at all. (I have put the permissions back after testing because our server admins do not want folders with write permissions on the server - not sure how to get round this either - you answered an earlier question on this topic advising that the webserver should have write permissions, but this has not been resolved yet.)
Any further help will be very much appreciated
Posted by admin (Graham Ellis), 14 February 2003Ah - I had so much fun with the clever graphics and adding the number on top of the page and it turns out you don't need all that clever stuff .... I'll answer the things that have mysified you but turn out to not be relevant in your situation here, then go on to give you a more tuned answer in a further follow up.
The whole business of using the image at all is to find something that can be included in a plain ole HTML web page that will cause some PHP to be run - you can't just say "please include this PHP in my HTML page" if the server isn't parsing it so you have to use something the browser will trigger - either an image or a piece of code in a browser-understood language. An image is a neat solution, as it also gives the ability to provide back something that changes to reflect the count if you had wanted that. As you don't need to do this (as it turns out) there are much easier ways.
The Explorer / Netscape differerence relates to different caching habits - on Netscape you often have to "shift-reload" or even load separately to get images to come up again after they've been cached; note the warning on the end of my initial post about counter reliability!
It's possible that the version of PHP on your server doesn't have all the Imagexxxxxx functions loaded; that may cause the problem that you describe there. If you don't want to modify the image, then you can use much easier functions to read and output the jpeg file, passing through binary data.
What else? The log file ... I just chose some data that's provided by PHP to write to the log file - I had a look through $_SERVER and chose what I thought looked useful. You're right - many of the things can be falsified, but it really depends what you're looking for what you put to that file.
I have a "PHP day" scheduled for tomorrow - I'm updating training notes, and I've added a note to that to have a look at counter code too. I'll post further ....
Posted by admin (Graham Ellis), 16 February 2003OK ... back to you on counting users. The metrics of your requirement
* You want to log ALL accesses to a PHP page
* You have to keep log AWAY from document directory
* You want to gather RELIABLE information
And you don't want to tell people the count, nor attempt to count
accesses to .html pages.
Firstly the matter of "all" to a PHP page shouldn't be a problem, as
such pages should not be cached; any web server worth its salt will
tell clients not to cache, and cache servers and proxies should obey
such instructions - after all, the ",php" or ".php4" extension is like
waving a red flag that says "I will be changing". Depending on browsers,
settings, etc, it MIGHT be that some browsers will cache a page on
occasions - but here's a question for you: "do you regard a pressing of
the Back button on a browser to be a fresh hit?". In any case, the
page will probably be reloaded if it's a form that's been submitted via
Keeping data AWAY from the document directory. Fine; I would go for a
plain text file to contain log records in a private directory. The log
file itself will need write permissions for the web server which (it
depends on how your admin is set up) is probably group write permissions.
How many log records will you be generating? If you've got tens of
visitors per minute sometimes (e.g. if you're running a class and you tell
everyone to go the page at the same instant, or if you have a site that's
very popular), you may wish to consider either:
a) File Locking or
b) Keeping log records in an SQL table
Your original question was about scripts to log; personally, I would tend
to "roll my own". A particular note - there are some logging scripts that
use offsite "counter farms" where the counting is done at someone else's
system. Sure means there's no writes on your system, but it puts up network
traffic, and adds in another cog - another potential machine that could
be unavailable when you're visited, and a system who's owner could be interested
in your statistics for his marketing or sales purposes.
Looking at the third issue - what can you log that's reliable? Not as much
as you might like! You're right that the User Agent (browser) can falsify
anything in the header it send. The IP address referring may not be the true
one for the browser, but a caching or proxy server, or the IP address may be
rewritten by some form of bridge. You should certainly record the timestamp,
any cookies you get back, hidden fields if you use them. I would record the IP
address and the user agent string - not as 100% reliable but because they'll
help you tell one user apart from another if you're logging a page that folks
keep coming back to. I don't think there's any way of telling visitors who are
using the same browser version through the same IP rewrite bridge apart unless
you do have cookies or hidden fields.
You've caught me in expansive mood this morning; I'll put together an example
that logs information that's as reliable as possible to a hidden text file, and
I'll use file locking to be double-plus sure that my PHP script won't damage
its own file by multithreading. Beware - file locking is a COOPERATIVE locking
system so processes can ignore the lock - it's up to YOU to lock in each script
that uses the file!
Posted by admin (Graham Ellis), 16 February 2003Here we go ... the code. Firstly, the page with the counter
The included file (also in the private directory):
I've gone really "over the top" with my file locking there! The $status variable does nothing, except provide a return from the included file that you can check to see whether your logging worked (2), failed at file lock time (1) or couldn't see the log file at all (0).
A quick script to look at the log file:
If you want to run the logging script, see
and if you want to see the log file
P.S. Note use of tabs as separators in the log file - makes it very easy to export the data to excel (if you must) or MySQL (much better ), and also to interpret the log file in PHP using explode or fgetcsv. Note also the pre-pending of "_" to fields that may be null - just ensures that something is visible in the fields if you need to see it on a browser
Posted by jill (jill), 17 February 2003Thanks for all this, and I have not completely got to grips with the code, but I did not manage to communicate the requirements quite right: We do wish to log and count all accesses to HTML pages, not php pages, we just do not need to show the resulting count in the page itself.
If you do have time to explain further, I will be very grateful, but as you have spent so much time already, I will understand if you don't!
Posted by admin (Graham Ellis), 18 February 2003Ah - some of the answers are a useful reminder to me of file locking and graphics manipulation issues, and I've been taking the opportunity to update training notes
Within an HTML page, you cannot usually add any of your own code which will count accesses on the server directly; web servers pass the HTML through without parsing it. The options you have are
a) Looking at server logs (do you have access to these?) as they may well provide you with enough information
b) Getting the server to parse the page even though it's HTML; you could simply rename the file (and links to it) as .php4 and use the code posted in my second answer. It's probable that the web server is set up to recognise index.php4 if you haven't got index.html anyway for the home page. You might also have access to the .htaccess file for the directory of interest, and you may be able to add
AddType application/x-httpd-php .html
into it (check with your sys admin to see if they're OK with you doing this!) so that HTML files are parsed
No easy answer on this one / counts / logging. If it was easy to log exactly who visited you with authourity, then it would be easy to add them to spam lists .... we would then all have to be very careful what web pages we visited.
Posted by jill (jill), 18 February 2003Many thanks for the advice and help - I shall now try and digest it.
Posted by admin (Graham Ellis), 20 July 2003Footnote on this thread - in PHP 4.3, there's a problem writing with a true type text font directly onto a full colour image, as was done in an earlier example in this thread. As an alternative, you can write to a new image with a transparent background and merge the two. A bit off topic; do post separately if you would like further details / example
Comment by anny (published 2011-02-25) Suggested link.
Thank you for your sharing! It is nice code for PHP Counter [#3894]
You can Add a comment or ranking or edit your own comments
Average page ranking - 2.0
PH: 01144 1225 708225 • FAX: 01144 1225 899360 • EMAIL: firstname.lastname@example.org • WEB: http://www.wellho.net • SKYPE: wellho