I got a POST
form, and it does send the data to the same file, and if use hit the back button in his browser, he can easily just re-send the data, and it'll be still read.
Is there any way to avoid such behaviour?
There are two general approaches.
First is the post-redirect-get
pattern where the user fills out a form on signup.php
which gets POST
ed to submit.php
which on successful completion sends back a REDIRECT
to thanks.php
. The browser sees the redirect response and issues a GET for thanks.php
. This works because without the redirect, hitting refresh would reload submit.php
causing a re-post form data warning and the POST
request to be double issued. The redirect solves this problem.
signup.php
-----------
...
<input type="text" name="email">
...
submit.php
----------
...
if ($_POST) {
// process data
header('Location: thanks.php');
}
...
thanks.php
----------
...
Thanks
...
The second approach is to embed a nonce
key in the form. This approach has the added benefit of preventing CSRF attacks as well. The approach here is to inject a hidden guid in your form:
<input type="nonce" value="<?= uniqid(); ?>">
The server will need to keep track of all nonce keys issues (in a database or something) and when it receives a form, it will process the form and delete the nonce key from the database. If the user resubmits the form a second time, the nonce key won't exist and the server can handle that by ignoring or issuing a warning.
The link Levi sent will answer for you. But in case you want an alternative, here is how I do it...
User posts to a class, like yours. same file. In the beginning of the class I do post processing. For this example I will make it very simple...
<?php
session_start();
//set form vars ahead of time so you can pre-populate the value attr on post
$form = array(
'name' => '',
'email' => ''
);
if(!empty($_POST))
{
//do some kind of validation...
$errors = array();
if(trim($_POST['name']) == '')
$errors[] = 'Please enter your name';
if(empty($errors))
{
$_SESSION['message'] = 'Thank you for participating';
header('location: /form.php'); // same file
exit;
}
else
{
// set the form vars to the post vars so you don't lose the user's input
$form['name'] = $_POST['name'];
$form['email'] = $_POST['email'];
$message = '<span style="color:red">';
foreach($errors AS $error)
{
$message .= $error."<br />";
}
$message .= '</span>';
$_SESSION['message'] = $message;
}
}
if(isset($_SESSION['message']))
{
echo $_SESSION['message'];
unset($_SESSION['message']);
}
?>
<form id="some_form" action="" method="post">
<fieldset>
<label for="name">Name</label> <input type="text" name="name" value="<?php echo $form['name']; ?>" />
<br /><br />
<label for="email">Email</label> <input type="text" name="email" value="<?php echo $form['email']; ?>" />
<br /><br />
<input type="submit" name="submit" value="Submit" />
</fieldset>
</form>
Now you can refresh over and over and not submit the form twice.
Edited to show further example. Obviously your validation and error handling should be a bit more sophisticated than this, but this should get you in the right direction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With