Forum Moderators: coopster

Message Too Old, No Replies

hit counter help

         

Skier88

12:03 am on Mar 18, 2010 (gmt 0)

10+ Year Member



My hit counter works fine in that it opens the appropriate file, increments the number, and rewrites the file with the new number of hits. However, it seems to be called twice with every page I load. I'm not sure why this is happening; it may actually be a .htaccess issue. But I'm hoping there is a simple if statement I can put before the counter to fix this.

My .htaccess redirects everything but images or structural components to one page:

RewriteEngine on
RewriteCond %{REQUEST_URI} !^/_structure/
RewriteRule !\.(gif|jpg|png|css)$ _structure/item.php

item.php contains a html template, and loads the appropriate content inside. At the bottom, the hit counter is this:

<?
$fn='hits.txt';
$hits=file($fn);
$hits[0]++;
$f=fopen($fn,'w');
fwrite($f,$hits[0]');
fclose($f);
?>

Any suggestions? Thanks for reading.

redhatlab

10:19 pm on Mar 19, 2010 (gmt 0)

10+ Year Member



Hi,

The PHP code looks good.

I think that either the JavaScript of the page or any other page like a frame might create the double hit.

There is also a chance that you might be using the code somewhere else in the page by mistake.

Matthew1980

10:45 pm on Mar 19, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there skier88,

I don't mean to be funny by pointing this out, and it won't affect the code execution, but it's good practice to use the full tags ie: <?php As short tags <? are only used if specified in the php ini file, and not all servers/host support the short tags format.

The hits counter code looks fine as redhatlab says.

<?php
$fn='hits.txt';
$hits=file($fn);
$hits['0']++;
$f=fopen($fn,'w');
fwrite($f,$hits[0]);
fclose($f);
?>

There was an extra ' in there, don't know whether this will do anything, but I'm a stickler :)

Cheers,
MRb

Skier88

11:06 pm on Mar 19, 2010 (gmt 0)

10+ Year Member



Thanks for the replies, but those can't be the issue. The page is a simple php experiment with no frames or javascript. And the code isn't repeated.

Matthew, I'm glad you pointed that out. When you teach yourself programming languages online you're always looking for more real validation of what you learned; while the ' was a careless mistake, I had no idea what the difference between <?php and <? was. Thanks :)

Brainstorming possible factors.... item.php loads content from several txt files - as in, "include $url.'/left.txt';", two or three times. But those show up in the page as they are on the server, without the structure inserted by item.php. Is it possible the server is correcting for a redirect loop?

Also, it is hosted at freehostia.com, so it is possible they are doing something weird.

Matthew1980

11:25 pm on Mar 19, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here is a thought skier88,

Try running the code in its own file before you put it where its meant to be, and as it's meant to function every time the page loads put it in it's own function then just call it at either the top of the script or the bottom as there will only be a few uS difference in execution time.

But before you go there, try the code in its own file hit F5 a few times to see if the code on its own does as required. This will prove the functionality of the snippet (fingers crossed!)

Also just put error_reporting(E_ALL); at the top of the script to see if there are any underlying issues that could cause anything - always worth doing when developing ;-p

[EDIT]
I should press preview sometimes. Doh :[

<?php
$fn='hits.txt';
$hits=file($fn);
$hits['0']++;
$f=fopen($fn,'w');
fwrite($f,$hits['0']);//I missed the ticks from here
fclose($f);
?>

Good luck :)

Cheers,
MRb

Skier88

11:40 pm on Mar 19, 2010 (gmt 0)

10+ Year Member



Thanks, but no luck. Loading the separate file does increment by only 1, but as soon as I put it in the main file, or call it from the main file, it goes up two or three at a time. No errors were reported. edit - and the ticks didn't help.

Matthew1980

2:00 pm on Mar 20, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there skier88,

Are you reading the file somewhere else to display the current hits that are stored, because if you are echoing the $hits['0']; var, this will always be 1 behind, as you are reading it before its updated I just tried this exact code on my local server, and for me it works fine, reads file -> Opens file to increment -> Writes the incremented value -> Closes handle.

Here is what I have just tried, and this is all that's in the file, the only other file in the dir is the hits.txt
Works as it should.


<?php
$fn='hits.txt';

$hits=file($fn);

print_r($hits);

$hits['0']++;

$f=fopen($fn,'w');

fwrite($f,$hits['0']);

$newhits =file($fn);

fclose($f);

print_r($newhits);

?>


I just used print_r() to see what was present after I hit F5 a few times (before & after read/write cycle)

Personally, I would call this file/function/code, as the last thing in the file, so that its the absolute last thing to be loaded into the browser, basically so that nothing can contaminate it.

Anyway, hope as you fix it soon ;-p

Cheers,
MRb

Skier88

3:10 pm on Mar 20, 2010 (gmt 0)

10+ Year Member



The only other time hits.txt is accessed is in prompt.txt, a file loaded by item.php before the hit counter only when it is displaying the site index.

<?
$hits=file('hits.txt');
echo 'Pageviews: '.$hits[0];
?>

So yes, since the hit counter is the absolute last thing in item.php it is displayed one behind, but that doesn't explain the increments of two. Besides, I don't know how I can print the value in the middle of the file and only read it in at the end.

I tried getting rid of the extra code, and just adding in "echo $hits[0];" after "$hits[0]++;", but it still incremented by one to three, usually two.

penders

3:41 pm on Mar 20, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



$hits['0']++;  
$f=fopen($fn,'w');
fwrite($f,$hits['0']);


Just another minor point (won't affect the running of the code in this instance), the array returned from the file() function has numeric keys, so you shouldn't really be using single quotes when referring to $hits['0'], it should simply be $hits[0] - as in the original post. PHP will type cast '0' (string) to 0 (int) in this case I think.

Matthew1980

4:58 pm on Mar 20, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there Skier88,

So from what you say, hits.txt is accessed by another process then. For a hits counter, the only time it is read & written to should be on page creation or page completion.

I would have it in a function to be called in the last part of the footer file, and make sure as it was the only reference to the echoed $var on the entire page.

What is the purpose of the other text file you refer to? If prompt.txt is a file calling this hits.txt shouldn't it be called prompt.php, especially as it more than likely contains the code you posted:-


<?php
$hits=file('hits.txt');
echo "Pageviews: ".$hits['0'];
?>


I hope as I haven't misread your post there at all ;-p

Cheers,
MRb

Skier88

8:51 pm on Mar 20, 2010 (gmt 0)

10+ Year Member



It should be called prompt.php. The reason it is prompt.txt is that item.php loads http://example.com/url/prompt.txt for every url, and on every other page it is just text, as filtered by the submission script. It is only for the index that I want to include php features, which can only be put there by directly editing them in. It's kind of ugly, but the point of the site isn't to be robust.

Anyway, yes, hits.txt is read, but not written to, earlier on every page. But that isn't the problem; as I said, I tried taking that part out and leaving just the part that I verified worked on its own page, and it still double counted. I also tried using a function as you said, but it also didn't fix it.

Thanks for the suggestions though.

Matthew1980

9:27 pm on Mar 20, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Skier88,

If its called prompt.txt, the php inside it won't be parsed, even though you specify its php with the tags (<?php ?>)

No matter what is function is, if it has PHP in it, name it .php as the extension, the read write process wouldn't be affected, you would just specify that in the fopen handle...

Also when I said "test it outside of the file", I meant literally, place that same code in a new file in a new folder and try it that way, I tried similar, and it functions fine (Previous post). So that leads me to think that the index file or wherever it's being placed in has something on it, or even an extra include somewhere that is calling this file more than once during page creation.

Sorry to go on, but I'm thinking from all angles here.

Cheers,
MRb

Skier88

7:43 pm on Apr 3, 2010 (gmt 0)

10+ Year Member



Hi MrB, I just thought I'd get back to you on this, since you've been helping me so much. It turns out that it was something to do with chrome's optimizations - the problem was not present in other browsers. I'm still not sure how to filter it, but at least I know there isn't something wrong with the code. And again, thanks for your help.

londrum

7:56 pm on Apr 3, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



some browsers can be set-up to automatically fetch the next page before you need it, to speed up page display time.

maybe your browser is loading the page, increasing the count by one, and then fetching the next page, increasing it by one again.

if that's what it is, maybe you could do something like getting the counter to check that the URL matches the script that called it.

Boxkites

10:36 am on Apr 4, 2010 (gmt 0)

10+ Year Member



Here's one I use, it works great.
You will have two files, one called "count.php"or whatever you want and the other called "count.txt"or whatever you want, LOL.

Add the following code into the "count.php" file.

<?php
$file = "count.txt";

if (file_exists($file)) {
$fp = fopen("$file", "r+");
flock($fp, 1);
$count = fgets($fp, 4096);
$count += 1;
fseek($fp,0);
fputs($fp, $count);
flock($fp, 3);
fclose($fp);
} else {
echo "Can't find the darn file, check '\$file'<br />";
}
?>


Then just Add:
<?php include ("count.php");?> 

into the page you want to count.
To show the number on the page, add:
<?php include ("count.txt");?>

Easy peasy, hope this helps.
Robert

Boxkites

10:58 am on Apr 4, 2010 (gmt 0)

10+ Year Member



I forgot but you can also use the count.php for all your pages, have a txt file for all your pages and just change the following:
$file = $countPage ; 


And on the page to be counted add this code:


<?php
$countPage = "ThisPageName.txt"; /* whatever the page name*/
include ("count.php");
?>


Cheers.
R

Matthew1980

5:31 pm on Apr 5, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there Skier88,

At least as you have identified your problem, that's good. I'm intrigued now though, are you saying that for one browser your hits counting is right, and other's it's not? I personally don't use chrome *other than browser compatibility* and FF is my main one, I don't like the "feel" of chrome. I digress.

What do you mean by filter exactly? Or am I missing your point?

Cheers,
MRb