0

I know this is a simple question but I downloaded a PHP Counter script from http://www.stevedawson.com/scripts/text-counter.php

which is the first result on google for PHP counter scripts and it worked great as expected.

I tried to see if it messes up by holding refresh in my browser after 255 requests it overflowed back to 0. How would I fix this script? I think the culprit is the filesize() which probably gets only 1 byte of data but it doesn't make sense since 255 is actually 3 bytes of data right? since it saves in plain-text format?

Why would it overflow? it's even PHP it shouldn't overflow just automatically mutate into a bigger datatype.

<?php
    $orderCountFile = "order_num_count.txt";
    if (file_exists($orderCountFile)) {
        $fil = fopen($orderCountFile, r);
        $dat = fread($fil, filesize($orderCountFile)); 
        echo $dat+1;
        fclose($fil);
        $fil = fopen($orderCountFile, w);
        fwrite($fil, $dat+1);
    } else {
        $fil = fopen($orderCountFile, w);
        fwrite($fil, 1);
        echo '1';
        fclose($fil);
    }
?>

Yeah I started to remake the script into another purpose I want to use it to keep track of order numbers for my website.

For a fix I think I have to recast $dat into a bigger integer type but can you even cast in PHP?

Also those r and w are suppose to be strings i think but they are used as constants but it doesn't seem to cause any troubles afaik.

SSpoke
  • 5,656
  • 10
  • 72
  • 124
  • A byte can represent the numbers 0-255. http://en.wikipedia.org/wiki/Byte – Kai May 30 '14 at 22:59
  • Yeah I was wrong it doesn't overflow but it does reset to 0.. if you refresh the script very fast.. it's probably a read/write race issue but I still can't figure it out. – SSpoke May 30 '14 at 23:01
  • Oh I found a related question probably same thing http://stackoverflow.com/questions/5250118/how-to-keep-this-counter-from-reseting-at-100-000?rq=1 – SSpoke May 30 '14 at 23:03

1 Answers1

1

Use file_get_contents and file_put_contents instead. You still have to consider, that there is a hard limit for that counter as well (see PHP_INT_MAX), but it's significantly higher.

<?php
$file = "counter.txt";
$counter = 0;
if (file_exists($file)) {
  $counter = file_get_contents($file);
}

$counter = $counter + 1;
file_put_contents($file, $counter);
echo $counter;
Kevin Sandow
  • 4,003
  • 1
  • 20
  • 33
  • I think could the problem be multiple scripts running simultaneously accessing the same file system and causing a race condition like in threading? It doesn't seem to stop at `255`.. I was wrong, now it got up to `280`. But it still is bugged. – SSpoke May 30 '14 at 23:00
  • Yeah but isn't the race condition http://stackoverflow.com/questions/5250118/how-to-keep-this-counter-from-reseting-at-100-000?rq=1 still possible without file locking those `file_get_contents` / `file_put_contents`? or are they safe? – SSpoke May 30 '14 at 23:07
  • Yes, this would still apply. There is a possibility to prevent resetting when you add a third parameter to `file_put_contents`: the flag `EX_LOCK`. But you could still skip a few counters between the read and the write operation during heavy load, in those cases a file based counter might not be a good solution at all. – Kevin Sandow May 30 '14 at 23:14
  • Can I make the other php scripts stall up before even reading not to get outdated values until the previous ones complete anyway to do that? – SSpoke May 30 '14 at 23:19
  • Well that's exactly what the the solution in the linked post does, if locks the file after creating the handle, so no other (PHP) processes can read the file, before the handle gets closed or unlocked. But there was another comment mentioning a database for this operation, since they already have concurrency build-in. – Kevin Sandow May 30 '14 at 23:24
  • So why will I miss a few hits is that because some scripts will load up outdated hits? and drop other hits to a outdated value? – SSpoke May 30 '14 at 23:27
  • The missed hits were with the solution I posted here, but the solution to the question you linked earlier doesn't miss anything. I only might slow down the webserver because multiple processes might be waiting to access the file - but that highly depends on your traffic. – Kevin Sandow May 30 '14 at 23:29
  • Than it's perfect I wan't to avoid running mysql for something this simple keep this script very portable low dependence on other tools too, I guess I'll just accept your answer as the right one, since I found my answer. – SSpoke May 30 '14 at 23:33