I have a php page with a form. When user submits the page then the database is updated. The problem comes when after submit user hits refresh button of browser. This refresh causes the form to be submitted again.

As a fix I was thinking if we can empty $_POST array so that refresh would not resubmit the page. Do you think it's a good approach for solving this situation or do you have any other better idea.

09-12-2012, 06:33 AM

codingrox

I have tried resetting the array but it's of no use. It's the browser which keeps all the values with it and does a post again.

09-12-2012, 06:42 AM

poyzn

form code please

09-12-2012, 11:43 AM

GreenFanta

You could set up a session variable, set the session variable to 1 on database update and then if the database update is run again and the session variable is equal to 1 then redirect the user to a different page or else warn them etc... Then you could just specify other pages setting the session variable to 1 if need be.

Regards

Matthew

09-12-2012, 12:53 PM

AndrewGSW

Quote:

Originally Posted by GreenFanta

You could set up a session variable, set the session variable to 1 on database update and then if the database update is run again and the session variable is equal to 1 then redirect the user to a different page or else warn them etc... Then you could just specify other pages setting the session variable to 1 if need be.

Regards

Matthew

I don't think solutions to this are straight-forward. For the above example, suppose someone is submitting the form a second time but with different data; if the session value is already 1 then it will prevent the submission of the second set of data.

Also, when they navigate away from the page, the session value would need to be reset to 0.

There's a similar solution discussed here, although I haven't tried it myself yet.

09-12-2012, 01:11 PM

vroom

If the data being stored in a database you could...

- create a suitable unique key to reject duplicate records
- check for the same data already sitting in the database

Then, in theory, all you need to do is give the user an appropriate error message upon resubmitting the form.

09-12-2012, 05:23 PM

Len Whistler

Quote:

Originally Posted by codingrox

I have a php page with a form. When user submits the page then the database is updated. The problem comes when after submit user hits refresh button of browser. This refresh causes the form to be submitted again.

As a fix I was thinking if we can empty $_POST array so that refresh would not resubmit the page. Do you think it's a good approach for solving this situation or do you have any other better idea.

No the problem here is simply refreshing the page asks the user to resubmit the data in its entirety which in turn becomes a new post request identical to the previous.
The way to get around that is to use a token on your form. It doesn't matter that its modifiable at all, but effectively what you do is specify a session value with this token, and apply that to the form. Then you check if the form token provided matches the token in the session. If it does, insert the data and destroy the token. If it doesn't simply indicate that the token has already been used. This will prevent the same data from being inserted or modified multiple times. It's much simpler than even the code on the blog link provided here.

PHP Code:

<?php

session_start();
$_SESSION['token'] = sha1(microtime(true)); // doesn't matter what this is, so long as it has randomness to it. Even microtime(true) is sufficient.
?>
<form ...>
<input type="hidden" name="token" value="<?php echo $_SESSION['token'];?>" />
</form>

Simple as that.
Hitting the back button shouldn't regenerate the token and add it to the session since the page is not re-requested from the server. So therefore the request to retransmit the post will include the previous token which will not match the session token.

If the page itself is a brand new request and the fields are filled in with the same data and submitted, there is no way to detect that this behaviour has occurred. You have to rely on your constraints to detect a duplicate, which depending on the purpose and structure depends if its doable. Every once and awhile I can manage to get a dual post here on the forums for example.

09-12-2012, 09:01 PM

AndrewGSW

@Fou Lu. Thank you, I like this :thumbsup:

But my form and form-processing code are on the same page. Does this present a problem? I'm thinking particularly of having unset() the token and then attempting to display it (hidden) in the form.

09-12-2012, 09:19 PM

Fou-Lu

That shouldn't be an issue. So long as a new unique token is created after consuming the new one, a resubmit of a post would contain the old token which won't match the new one.
Always unset the token once its been used though. Even if on the same page it gets recreated.

That's fine. It doesn't matter if the token is created each time, even if it goes unconsumed. Ideally you wouldn't do this, but if you are submitting to itself and always showing the form, you really have no alternative but to keep generating a new one.

Quote:

Originally Posted by codingrox

Lovely... thanks for your response...

If multiple users are on the same web page then wouldn't $_SESSION keep changing and hence it would never match with token stored in hidden variable?

Okay, I have checked this and it does remember the session token stored earlier and it just works fine.

But how does it do it. How does it know which user had which token variable stored in session variable.

Sessions are not shared by multiple clients. Session id's are stored in a browser's cookies or if cookies are not available it is passed through the querystring. If use_trans_sid is enabled, it will automatically append it, otherwise you have manually append it.

09-13-2012, 06:40 AM

codingrox

What's the point of unsetting token in session variable if we are going to set it anyways to a new value??