PHP Counter (Read/Write) Increments on Page Refresh

Hi – I have an issue with a PHP Counter script. When a certain link is clicked, the script is supposed to read in a .txt file and assign it to a variable, increment the value by 1, then write the new value to the txt file. Everything works as expected EXCEPT for the fact that the value increments upon a page refresh. Is there a way to prevent this from happening? I’ve read that this can be achieved using jQuery, but I don’t know enough about AJAX to implement it successfully. Plus, if it is possible to keep it all in PHP, that would be a lot better. Please advise (script below):


<?php
    session_start(); 
    $counter_name = 'emailCounter.txt';
    
    // Check if a text file exists. If not create one and initialize it to zero.
    if (!file_exists($counter_name)) {
          $f = fopen($counter_name, "w");
          fwrite($f,"0");
          fclose($f);
        }

    // Read the current value of our counter file
         $f = fopen($counter_name,"r");
         $counterVal = fread($f, filesize($counter_name));
         fclose($f);
         echo '<p>' . $counterVal .'</p>';
        }
        
        // Increment counter value by one
        if (isset($_GET ['link'])){
            $link = $_GET['link'];
            if ($link == '1') {
                $counterVal++;
                $f = fopen($counter_name, "w");
                fwrite($f, $counterVal);
                fclose($f);
            }
        }        
    ?>
  <a href="?link=1">Click me</a>

How do you differentiate a page view from a page view?

There are a couple of tricks you can pull - using sessions mostly, that would count each page only once… but that brings the opposite problem - you only count once, legit pageclick or refresh.

If I understand you correctly, you wish to keep count of the amount of times a link is clicked. Is that correct?

If this is the case I would attach an event listener to the link, prevent the link’s default action when it is clicked, then fire off an AJAX request to the PHP script that increments the counter and saves it to the file.

Hi Pullo - Could you provide a simple code example?

I’m off to work right now (late in fact).

IF no one has a suggestion as to how this might be solved in PHP, when I come back, I’ll move this to the JS forum and we’ll continue from there (with a code sample, of course).

Ok then. We need two files.

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Counter increment script</title>
  </head>
  <body>
    <a class="counter" href="#">Click me</a>

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script>
      $("a.counter").on("click", function(e){
        e.preventDefault();
        $.ajax({
          url: 'increase_counter.php',
          type: 'POST',
          success: function(counterVal){
            alert("The link has been clicked " + counterVal + " times.")
          }
        });
      });
    </script>
  </body>
</html>

This contains a simple link. As mentioned before, when it is clicked, it fires off an AJAX request to a script in the same directory entitled increase_counter.php. To offer some feedback, it then alerts the result back to the user.

increase_counter.php

<?php
  $counter_name = 'emailCounter.txt';

  if (!file_exists($counter_name)) {
    $f = fopen($counter_name, "w");
    fwrite($f,"0");
    fclose($f);
  }

  $f = fopen($counter_name,"r");
  $counterVal = fread($f, filesize($counter_name));
  fclose($f);

  $counterVal++;

  $f = fopen($counter_name, "w");
  fwrite($f, $counterVal);
  fclose($f);

  echo $counterVal;
?>

This will check for the presence of a counter file. If it’s not found then it is created, otherwise the current value is read in, incremented, saved and returned back to the page.

Have a play with that and let us know when you’ve got it working.

Hi Pullo - Sorry for the late response. THANK YOU - that basically did it. I just had to rework a few things in the jQuery code for a specific situation. I’m posting those changes below, in the same spirit of sharing information and in hopes that it may help someone in the future.

Instead of alerting that the link was clicked, I wanted to show the numerical change on the page. So I changed this line…

alert("The link has been clicked " + counterVal + " times.")

to this…

$(".container").html('<p>' + counterVal + '</p>');

Finally, to display the counterVal on page load, I had to copy a few lines of code from increase_counter.php, and include it on the index page itself. Like so…

<?php
        $counter_name = 'emailCounter.txt';
        $f = fopen($counter_name,"r");
        $counterVal = fread($f, filesize($counter_name));
        fclose($f);
         
        echo '<div class="container"><p>' . $counterVal .'</p></div>';
?>

THANKS AGAIN FOR YOUR HELP!

Hey,

No problem.

You can initialize the counter in the PHP script already (as you are doing), or you could also do:

$("a.counter").trigger("click");

in your JavaScript.

And, the PHP could probably be tidied up a little:

<?php
  $counter_name = 'emailCounter.txt';

  if (!file_exists($counter_name)) {
    $f = fopen($counter_name, "w");
    fwrite($f,"0");
    fclose($f);
  }

  $counterVal = file_get_contents($counter_name);
  $counterVal++;

  $f = fopen($counter_name,"w");
  fwrite($f, $counterVal);
  fclose($f);

  echo $counterVal;
?>
1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.