tags:

views:

750

answers:

3

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?

+2  A: 

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');
}
Michael Wales
+12  A: 

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

Tom Wright
Great answer, PRG is definitely the way to go: http://en.wikipedia.org/wiki/Post/Redirect/Get
Neil Williams
Do I need the full url for the header?
wheresrhys
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.
wheresrhys
Sounds like you have output before your header. You could die('here'); and see what the application is sending.
Eddy
@Rhys, yes you need the full url. Try Eddy's suggestion for your error. Otherwise, perhaps you could use a different form of redirect.
Tom Wright
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).
Ciaran McNulty
Huh. That's pretty nifty. :)
Tom Wright
+6  A: 

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

David Caunt