Go Back   CodingForums.com > :: Server side development > PHP

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 09-12-2012, 06:14 AM   PM User | #1
codingrox
New Coder

 
Join Date: Jun 2012
Posts: 31
Thanks: 12
Thanked 0 Times in 0 Posts
codingrox is an unknown quantity at this point
Refresh Resubmits the page

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.
codingrox is offline   Reply With Quote
Old 09-12-2012, 06:33 AM   PM User | #2
codingrox
New Coder

 
Join Date: Jun 2012
Posts: 31
Thanks: 12
Thanked 0 Times in 0 Posts
codingrox is an unknown quantity at this point
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.
codingrox is offline   Reply With Quote
Old 09-12-2012, 06:42 AM   PM User | #3
poyzn
Regular Coder

 
poyzn's Avatar
 
Join Date: Nov 2010
Posts: 265
Thanks: 2
Thanked 61 Times in 61 Posts
poyzn is on a distinguished road
form code please
__________________
Ushousebuilders.com
poyzn is offline   Reply With Quote
Old 09-12-2012, 11:43 AM   PM User | #4
GreenFanta
New Coder

 
Join Date: Aug 2011
Posts: 46
Thanks: 9
Thanked 2 Times in 2 Posts
GreenFanta is an unknown quantity at this point
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
GreenFanta is offline   Reply With Quote
Old 09-12-2012, 12:53 PM   PM User | #5
AndrewGSW
Senior Coder

 
Join Date: Apr 2011
Location: London, England
Posts: 2,120
Thanks: 15
Thanked 354 Times in 353 Posts
AndrewGSW will become famous soon enough
Quote:
Originally Posted by GreenFanta View Post
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.
__________________
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
Validate your HTML and CSS
AndrewGSW is offline   Reply With Quote
Old 09-12-2012, 01:11 PM   PM User | #6
vroom
New Coder

 
Join Date: Sep 2012
Posts: 71
Thanks: 0
Thanked 8 Times in 8 Posts
vroom is an unknown quantity at this point
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.
__________________
I'm sure some folks around here would be happy to get more involved if people posted tasks here and offered a few bucks.

Beware, code snippets in my posts are meant as examples... they certainly may contain typos.
vroom is offline   Reply With Quote
Users who have thanked vroom for this post:
codingrox (09-13-2012)
Old 09-12-2012, 05:23 PM   PM User | #7
Len Whistler
Senior Coder

 
Len Whistler's Avatar
 
Join Date: Jul 2002
Location: Vancouver, BC Canada
Posts: 1,323
Thanks: 26
Thanked 100 Times in 100 Posts
Len Whistler is on a distinguished road
Quote:
Originally Posted by codingrox View Post
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.

The code below should work.

PHP Code:
if (isset($_POST['submit'])) {
$comments $_POST['comments'];
mysql_query("INSERT INTO comments (comments) VALUES ('$comments')");

__________________
Leonard Whistler
Len Whistler is offline   Reply With Quote
Users who have thanked Len Whistler for this post:
codingrox (09-13-2012)
Old 09-12-2012, 05:38 PM   PM User | #8
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,645
Thanks: 4
Thanked 2,450 Times in 2,419 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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>
Then when submitted:
PHP Code:
<?php

session_start
();
if (isset(
$_POST['token'], $_SESSION['token']) && strcmp($_POST['token'], $_SESSION['token']) == 0)
{
    
// Its good
    
unset($_SESSION['token']);
    
// go ahead with everything else.
}
else
{
    print(
'The token provided is expired');
}
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.
Fou-Lu is offline   Reply With Quote
Users who have thanked Fou-Lu for this post:
codingrox (09-13-2012)
Old 09-12-2012, 09:01 PM   PM User | #9
AndrewGSW
Senior Coder

 
Join Date: Apr 2011
Location: London, England
Posts: 2,120
Thanks: 15
Thanked 354 Times in 353 Posts
AndrewGSW will become famous soon enough
@Fou Lu. Thank you, I like this

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.
__________________
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
Validate your HTML and CSS
AndrewGSW is offline   Reply With Quote
Old 09-12-2012, 09:19 PM   PM User | #10
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,645
Thanks: 4
Thanked 2,450 Times in 2,419 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Users who have thanked Fou-Lu for this post:
AndrewGSW (09-12-2012)
Old 09-12-2012, 10:29 PM   PM User | #11
AndrewGSW
Senior Coder

 
Join Date: Apr 2011
Location: London, England
Posts: 2,120
Thanks: 15
Thanked 354 Times in 353 Posts
AndrewGSW will become famous soon enough
Thanks again. I just want to clarify that I've got the order correct:

PHP Code:
session_start(); 

// if submitted..
if (isset($_POST['token'], $_SESSION['token']) && strcmp($_POST['token'], $_SESSION['token']) == 0) 

    // Its good 
    unset($_SESSION['token']); 
    // go ahead with everything else.
    $_SESSION['token'] = sha1(microtime(true)); // doesn't matter what this is..
    // process form data..

else 

    print('The token provided is expired');
    // don't process form data..
    
}
// else if not submitted..
    $_SESSION['token'] = sha1(microtime(true));

<form ...> 
    <input type="hidden" name="token" value="<?php echo $_SESSION['token'];?>" /> 
</form>
__________________
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
Validate your HTML and CSS
AndrewGSW is offline   Reply With Quote
Users who have thanked AndrewGSW for this post:
codingrox (09-13-2012)
Old 09-12-2012, 11:02 PM   PM User | #12
AndrewGSW
Senior Coder

 
Join Date: Apr 2011
Location: London, England
Posts: 2,120
Thanks: 15
Thanked 354 Times in 353 Posts
AndrewGSW will become famous soon enough
I think I had this wrong: I recreate the session variable on EVERY occasion, but only unset it if the submission proceeds. As follows?

PHP Code:
session_start();  

// if submitted.. 
if (isset($_POST['token'], $_SESSION['token']) && strcmp($_POST['token'], $_SESSION['token']) == 0)  
{  
    // Its good  
    unset($_SESSION['token']);  
    // go ahead with everything else. 
    // process form data.. 
}  
else  
{  
    print('The token provided is expired'); 
    // don't process form data.. 
     

// create new token on every occasion..
$_SESSION['token'] = sha1(microtime(true)); 

<form ...>  
    <input type="hidden" name="token" value="<?php echo $_SESSION['token'];?>" />  
</form>
__________________
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
Validate your HTML and CSS
AndrewGSW is offline   Reply With Quote
Old 09-13-2012, 01:32 AM   PM User | #13
codingrox
New Coder

 
Join Date: Jun 2012
Posts: 31
Thanks: 12
Thanked 0 Times in 0 Posts
codingrox is an unknown quantity at this point
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.

Last edited by Fou-Lu; 09-13-2012 at 04:14 AM..
codingrox is offline   Reply With Quote
Old 09-13-2012, 04:17 AM   PM User | #14
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,645
Thanks: 4
Thanked 2,450 Times in 2,419 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
Quote:
Originally Posted by AndrewGSW View Post
I think I had this wrong: I recreate the session variable on EVERY occasion, but only unset it if the submission proceeds. As follows?

PHP Code:
session_start();  

// if submitted.. 
if (isset($_POST['token'], $_SESSION['token']) && strcmp($_POST['token'], $_SESSION['token']) == 0)  
{  
    // Its good  
    unset($_SESSION['token']);  
    // go ahead with everything else. 
    // process form data.. 
}  
else  
{  
    print('The token provided is expired'); 
    // don't process form data.. 
     

// create new token on every occasion..
$_SESSION['token'] = sha1(microtime(true)); 

<form ...>  
    <input type="hidden" name="token" value="<?php echo $_SESSION['token'];?>" />  
</form>
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 View Post
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.
Fou-Lu is offline   Reply With Quote
Old 09-13-2012, 06:40 AM   PM User | #15
codingrox
New Coder

 
Join Date: Jun 2012
Posts: 31
Thanks: 12
Thanked 0 Times in 0 Posts
codingrox is an unknown quantity at this point
What's the point of unsetting token in session variable if we are going to set it anyways to a new value??
codingrox is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 10:57 AM.


Advertisement
Log in to turn off these ads.