Avoiding form resubmit in php when pressing f5
Asked Answered
M

11

14

I have the following code on my site (using php and smarty) to try and avoid a form resubmitting when I hit f5:

if ($this->bln_added == false) {
    if (isset($_POST['submit'])) {
        $this->obj_site->obj_smarty->assign('title', $_POST['tas_heading']);
        $this->obj_site->obj_smarty->assign('desc', $_POST['tas_description']);
    }
} else {
    $this->obj_site->obj_smarty->assign('title', '');
    $this->obj_site->obj_smarty->assign('desc', '');
    unset($_POST);
}

bln_added is false by default, but changes to true once the form is successfully submitted. The smarty variables title and desc are used in the template to keep the form content there in case there is a user error and they need to change what they entered.

If the form is submitted successfully it sets bln_added = true, so the second bit of code should not only clear the form fields, but also empty $_POST. But if I press f5 the post data is still there.

Any ideas?

Minette answered 6/4, 2009 at 18:6 Comment(0)
D
41

Your method could work in theory, but there's a much easier way.

After submitting the form successfully, perform a redirect. It doesn't matter where to, but it'll clear the $_POST.

header('Location: http://www.example.com/form.php');

In your case, it sounds like you want to redirect to the page you're already on. Append a $_GET parameter to the URL if you want to display a confirmation message.

Hope this helps,

Tom

Devonna answered 6/4, 2009 at 18:12 Comment(9)
Great answer, PRG is definitely the way to go: en.wikipedia.org/wiki/Post/Redirect/GetNutbrown
Do I need the full url for the header?Minette
Just tried it out and it's conflicting with a header set somewhere else in the application. I didn't write it all so have no idea where to go to stop it setting.Minette
Sounds like you have output before your header. You could die('here'); and see what the application is sending.Palestra
@Rhys, yes you need the full url. Try Eddy's suggestion for your error. Otherwise, perhaps you could use a different form of redirect.Devonna
I believe the full URL is not required, and when you supply a relative URL either PHP or Apache will resolve it to an absolute URL to send to the client (not sure which stage in the chain this takes place).Horning
Isn't it easier to set $_POST = ''; Just curious, not sure it will help.They
@TomWright That's in theory a nice idea, but in real world this is a horrible pattern as there's no clean way to transport feedback.Hertzfeld
@Panique Afraid I (and 23 upvotes) will have to disagree with you on this one. PRG is very widely used and more than adequate for "transporting" feedback, provided a get parameter (the G in PRG) is used.Devonna
S
10

The solution is a pattern commonly known as Post/Redirect/Get

Soloma answered 6/4, 2009 at 18:45 Comment(0)
L
6

The best way to handle forms is to use self-submission and a redirect. Something like this:

if (isset($_POST)) {
  // Perform your validation and whatever it is you wanted to do
  // Perform your redirect
}

// If we get here they didn't submit the form - display it to them.

Using the CodeIgniter framework:

function index() {
  $this->load->library('validation');
  // Your validation rules

  if ($this->form_validation->run()) {
    // Perform your database changes via your model
    redirect('');
    return;
  }
  // The form didn't validate (or the user hasn't submitted)
  $this->load->view('yourview');
}
Locomotive answered 6/4, 2009 at 18:12 Comment(0)
P
2

You can rewrite your form-submit into AJAX-way. If you need to show HTML-content, return it in JSON-format and insert with JavaScript(jQuery for example.)

Pyrexia answered 17/10, 2014 at 5:32 Comment(0)
T
1

I solved this (in php) by:

  1. in the form add a unique identifier (id+counter) not based on time() (!!!)

  2. post to a separate file (postform.php) that checked for a session with that unique identifier

  3. a) if session with unique identifier was NOT found: post to the database and fill session with unique identifier

    b) if session with unique identifier was found: do nothing

  4. after either 3a/3b redirect to result page with header('Location: http://mydomain.com/mypage')

Result is:
no resubmit actions on either refresh/backbutton and only resubmit warning on double click backbutton (but no resubmit action)

Tinney answered 19/12, 2011 at 10:24 Comment(1)
Thank you paul, I got a basic idea, why we should not use form submission in the same page. Previous times I was using form submit to the same page. After Handling the form, I redirect it to self with some get parameter.Gourd
B
1

Use Header location after successful post action

header('Location: '.$_SERVER['HTTP_REFERER']);
Buddy answered 23/5, 2013 at 13:28 Comment(0)
A
1

It works for me if I use either header() or exit() at the end of my code, for example, after I save some data.

Ailment answered 13/9, 2015 at 3:9 Comment(0)
D
1

The best method I found is using javascript and css. Common php redirection method header('Location: http://www.yourdomain.com/url); will work but It cause warning " Warning: Cannot modify header information - headers already sent" in different frameworks and cms like wordpress, drupal etc. So my suggestion is to follow the below code

echo '<style>body{display:none;}</style>'; 
echo '<script>window.location.href = "http://www.siteurl.com/mysuccesspage";</script>'; 
exit;

The style tag is important otherwise the user may feel like page loaded twice. If we use style tag with body display none and then refresh the page , then the user experience will be like same as php header('Location: ....);

I hope this will help :)

Descendible answered 23/6, 2017 at 12:30 Comment(0)
D
1

the answer you are looking for is this magic one liner: header('Location: '.$_SERVER['HTTP_REFERER']);

e.g

if(isset['submit']){
    //insert database
    header('Location: '.$_SERVER['HTTP_REFERER']);
}
Downtown answered 13/6, 2020 at 11:30 Comment(0)
L
0

Header redirect after post is necessary, but insufficient.

In PHP side after submitting the form successfully, perform a redirect. Eg. header('Location: http://www.example.com/form.php');

But it is not enough. Some users press links twice (doubleclick). A JavaScript is required that would disable submit button after first click.

Lumbye answered 27/11, 2011 at 16:44 Comment(0)
G
0

Try my own one, maybe it isn't best solution (done quickly), but I've test it and it works. Tested on Chrome. Click to see how it looks BR

 <?php 
session_start(); // Start session
?>
<html>
 <head>
  <title>
    Test
  </title>
 </head>
 <body>
   <form name="test" action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post">
   <input type="text" name="name"><br>
   <input type="submit" name="submit" value="Submit Form"><br>
  </form>

  <?php

  if(isset($_POST['submit']))
    {
     $_SESSION['name'] = $_POST['name']; //  Assign $_POST value to $_SESSION variable
      header('Location: refresh.php'); // Address of this - reloaded page - in this case similar to PHP_SELF
    } else session_destroy(); // kill session, depends on what you want to do / maybe unset() function will be enough

  if(isset($_SESSION['name']))
    {
     $name = $_SESSION['name'];

     echo "User Has submitted the form and entered this name : <b> $name </b>";
     echo "<br>You can use the following form again to enter a new name."; 
    }
  ?>
 </body>
</html>
Gruel answered 2/2, 2018 at 21:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.