Resubmitting forms upon page refresh or reload in PHP

A common problem with forms is the annoying resubmit when the user reloads or refreshes a page. This can result in duplicate database records if not dealt with properly.

There are a number of simple solutions to this problem, I’ll go through a couple below.

1. Use two files (one with the form on and one to process), and redirect back to the first page when the processing is done.

Here’s some sample code for the form page (form.htm):

<form name="form1" method="post" action="process.php">
<input type="text" name="text" id="text">
<input type="submit" name="submit" id="submit" value="Submit">
</form>

and here’s some sample code for the processing page (process.php):

<?php
if (isset($_POST['submit'])) {
$text = $_POST['text'];
$query = mysql_query("Insert into our database etc");
header("Location: form.htm");
}
?>

This uses PHP header to redirect the user back to the form page when the form is processed, or if the user directly visits process.php without the form submission. Bear in mind this is only example code and so is not complete or secure.

2. Use two files (one with the form on and to process and one when finished), redirecting to the second page when finished.

Here is some sample code for the process/form page (form.php):

<?php
if (isset($_POST['submit'])) {
$text = $_POST['text'];
$query = mysql_query("Insert into our database etc");
}
header("Location: thanks.htm");
?>
<form name="form1" method="post" action="form.php">
<input type="text" name="text" id="text">
<input type="submit" name="submit" id="submit" value="Submit">
</form>

and here’s the code for the final page (thanks.htm):

<p>Thanks for filling out our form!</p>

The user can still refresh the final page as much as they want as the processing was done elsewhere.

3. Use one file, doing all the processing and then displaying a thank you message.

This uses a $_GET to tell the script we’ve finished and display a message (form.php):

<?php
if ($_GET['success']) {
echo "Your text was saved successfully!";
} elseif (isset($_POST['submit'])) {
$text = $_POST['text'];
$query = mysql_query("Insert into our database etc");
header("Location: form.php?success=1");
}
?>
<form name="form1" method="post" action="form.php">
<input type="text" name="text" id="text">
<input type="submit" name="submit" id="submit" value="Submit">
</form>

I suppose you could change the echo to a die if you didn’t want to show the form, or add in a final else like this:

<?php
if ($_GET['success']) {
echo "Your text was saved successfully!";
} elseif (isset($_POST['submit'])) {
$text = $_POST['text'];
$query = mysql_query("Insert into our database etc");
header("Location: form.php?success=1");
} else {
?>
<form name="form1" method="post" action="form.php">
<input type="text" name="text" id="text">
<input type="submit" name="submit" id="submit" value="Submit">
</form>
<?php } ?>

so that the form would not be displayed when the Success text was.

4. Involve sessions

You could also involve sessions in your form by storing the POST variables in a session before processing, eg:

$_SESSION['postdata'] = $_POST;

and clearing the session once the processing had been done, eg:

unset($_SESSION['postdata'])

You could also enter a timestamp with each posted form and store this in a database, checking before processing for identical timestamps, it depends on the nature of your application and your personal preference.

Any comments/improvements welcome!