简体   繁体   中英

PHP only click counter counting when refresh page

I'm new into coding and programming world. I'm currently attending school which mostly teach about web development.

I was trying to record how many times the user clicks on to few buttons only with PHP sessions and I'm trying to keep all the code in single page.

It does work so far, but the only problem I have right now is that whenever I refresh the page, the counter of the last button I clicked raises up. And also when I click on the button with session_destroy(); function, it doesn't reset the session right away.

Is it actually possible with PHP? Or do I really need a database?

Code:

<?php
  session_start();

  $clickGreen = 0;
  $clickRed = 0;

  if(!isset($_SESSION['clickGreen']) && !isset($_SESSION['clickRed'])){
    $_SESSION['clickGreen'] = $clickGreen;
    $_SESSION['clickRed'] = $clickRed;
  }

  if(isset($_GET["SubmitGreen"]) && !empty($_GET['SubmitGreen'])){
    $_SESSION['clickGreen']++;
  }

  if(isset($_GET["SubmitRed"]) && !empty($_GET['SubmitRed']) ){
    $_SESSION['clickRed']++;
  }

  if(isset($_GET["SubmitRefresh"])){
    session_destroy();
  }

  $g = $_SESSION['clickGreen'];
  $r = $_SESSION['clickRed'];
?>
<html>
  <head>
    <style>
    </style>
  </head>
  <body>
    Cicks on green = <?php echo $g ?><br/>
    Clicks on red = <?php echo $r ?><br/>
    <form name="form1" method="get" action="index.php">
      <input type="submit" name="SubmitGreen" value="Green" />
      <input type="submit" name="SubmitRed" value="Red" />
      <input type="submit" name="SubmitRefresh" value="Refresh" />
    </form>
  </body>
</html>

You need to unset your $_GET array after confirming of its existence and values, otherwise it is still true in its existence and value when you refresh the page, hence the update of the click count on refresh.

The simple changes below which are commented to be prominent shall help you get the results you desire:

<?php
  session_start();

  $clickGreen = 0;
  $clickRed = 0;

  if(!isset($_SESSION['clickGreen']) && !isset($_SESSION['clickRed'])){
    $_SESSION['clickGreen'] = $clickGreen;
    $_SESSION['clickRed'] = $clickRed;
  }

  if(isset($_GET["SubmitGreen"]) && !empty($_GET['SubmitGreen'])){
    $_SESSION['clickGreen']++;
    unset($_GET["SubmitGreen"]);
  }

  if(isset($_GET["SubmitRed"]) && !empty($_GET['SubmitRed']) ){
    $_SESSION['clickRed']++;
    unset($_GET["SubmitRed"]);
  }

  if(isset($_GET["SubmitRefresh"])){
    session_destroy();
  }

  $g = $_SESSION['clickGreen'];
  $r = $_SESSION['clickRed'];
?>

You have to remove action="index.php" and replace it with nothing like below. And when you click on Refresh, your session is getting killed, and counters are reset to zero, but aren't shown right away as your page is not getting refreshed upon button submit. See my code below, after destroying the session I am refreshing the page back to your counter page, which looks neat.

Will appreciate your feedback.

 <?php
  session_start();

  $clickGreen = 0;
  $clickRed = 0;

  if(!isset($_SESSION['clickGreen']) && !isset($_SESSION['clickRed'])){
    $_SESSION['clickGreen'] = $clickGreen;
    $_SESSION['clickRed'] = $clickRed;
  }

  if(isset($_GET["SubmitGreen"]) && !empty($_GET['SubmitGreen'])){
    $_SESSION['clickGreen']++;
  }

  if(isset($_GET["SubmitRed"]) && !empty($_GET['SubmitRed']) ){
    $_SESSION['clickRed']++;
  }

  if(isset($_GET["SubmitRefresh"])){
    session_destroy();
    header("Refresh:0; url=timesCounter.php");
  }

  $g = $_SESSION['clickGreen'];
  $r = $_SESSION['clickRed'];
?>
<html>
  <head>
    <style>
    </style>
  </head>
  <body>
    Cicks on green = <?php echo $g ?><br/>
    Clicks on red = <?php echo $r ?><br/>
    <form name="form1" method="get" action="">
      <input type="submit" name="SubmitGreen" value="Green" />
      <input type="submit" name="SubmitRed" value="Red" />
      <input type="submit" name="SubmitRefresh" value="Refresh"  />
    </form>
  </body>
</html>

Check for the request method

Checking for the request method is going to give more confidence as to what the user is trying to. is s/he trying to submit the form information? or is s/he trying to simply read the information on the the page?

Change the form method

The first step for this solution is to change the submission method of the form. As written in the original question, there is no difference between reading the page and submitting the form; both are using GET to reach the server. By switching the form's method to POST , we'll be in a better position to establish what the user is trying to do and how the server should handle the request.

<form name="form1" method="post" action="index.php">
    <input type="submit" name="SubmitGreen" value="Green" />
    <input type="submit" name="SubmitRed" value="Red" />
    <input type="submit" name="SubmitRefresh" value="Refresh" />
</form>

Change the superglobal references

Now that the form is submitting in post, we need to change the existing conditions so that the values are validated properly.

if(!empty($_POST['SubmitGreen'])){
    $_SESSION['clickGreen']++;
}

if(!empty($_POST['SubmitRed']) ){
    $_SESSION['clickRed']++;
}

Notice that I didn't include the check on $_GET["SubmitRefresh"] ; this is intended, we'll address it in the next section.

Post Redirect Get

This will probably be the more complex part of this answer: making sure that when the user hits refresh, the server receives a GET request instead of a POST . For this, we'll use the well-known Post/Redirect/Get pattern. In essence, each time the user submits the form a POST we are going to internally redirect the user to the same page, but using GET instead. By doing this, we'll make sure that the counter does not increase when the user refreshes the page, or hits the backspace (this is issue is known as Duplicate Form Submission)

<?php
    // Initializing the session: this stays the same
    session_start();

    $clickGreen = 0;
    $clickRed = 0;

    if(!isset($_SESSION['clickGreen']) && !isset($_SESSION['clickRed'])){
        $_SESSION['clickGreen'] = $clickGreen;
        $_SESSION['clickRed'] = $clickRed;
    }

    // if the request is a POST, we update the counters, the redirect using GET
    if($_SERVER['REQUEST_METHOD'] === 'POST') {
        if(!empty($_POST['SubmitGreen'])){
            $_SESSION['clickGreen']++;
        }

        if(!empty($_POST['SubmitRed']) ){
            $_SESSION['clickRed']++;
        }

        // redirect to same page
        // or success/error page
        header('Location: index.php');
    }
    // if the request is a GET, we simply fetch the session to populate the form
    else {
        $g = $_SESSION['clickGreen'];
        $r = $_SESSION['clickRed'];
    }
?>
<html>
<!-- ... -->

Note: I removed isset() from some of the conditions since checking for both isset() and !empty() is redundant (see the PHP comparison table for more info)


Further Readings

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM