I'm not sure if this is specifically a PHP problem, but here we go. Is there a way to clear the POST variables when the user refreshes a page? Specifically, my webpage POSTs a form to update or delete a record from the database -- it POSTs to itself, however. But if the user then clicks the browser's refresh button, it will try to delete or modify a non-existent record. I would like, if the users presses the refresh button, that PHP processes the page as no POST variables are set. I have a button on the page entitled "Reload" that executes a short Javascript: onclick=window.location=<? echo PHP_SELF; ?> which accomplishes the desired effect. But it tries to resend the POST information if the browser refresh button is clicked.
I read something somewhere that seemed to imply this could be done with PHP sessions? Is this the way to go? If so, how?
Richard Lynch 3 February 2005 22:26:02 [ permanent link ]
Richard Morley wrote:> I'm not sure if this is specifically a PHP problem, but here we go. Is> there a way to clear the POST variables when the user refreshes a page?> Specifically, my webpage POSTs a form to update or delete a record from> the database -- it POSTs to itself, however. But if the user then clicks> the browser's refresh button, it will try to delete or modify a> non-existent record. I would like, if the users presses the refresh> button, that PHP processes the page as no POST variables are set. I have a> button on the page entitled "Reload" that executes a short Javascript:> onclick=window.location=<? echo PHP_SELF; ?> which accomplishes the> desired effect. But it tries to resend the POST information if the browser> refresh button is clicked.
A simple thing to do is to put an md5 hash into the POST data, then only do the insert if that md5 hash isn't already "used" when they hit refresh.
This avoids the hassle of re-direct headers and trying to follow programming logic bouncing from script to script.
Chris W. Parker 3 February 2005 22:42:32 [ permanent link ]
Richard Lynch <mailto:ceo@l-i-e.com> on Thursday, February 03, 2005 11:26 AM said:
A simple thing to do is to put an md5 hash into the POST data, then> only do the insert if that md5 hash isn't already "used" when they> hit refresh. >
This avoids the hassle of re-direct headers and trying to follow> programming logic bouncing from script to script.
Come now, let's not be so dramatic.
"hassle of re-direct":
<?php
header("Location: http://fq.dn/page.ext");
?>
"programming logic bouncing from script to script":
It would be the same logic/handling of the form, just split across two pages. Not really much changing is necessary. Except of course that you will have to send data back to the form page via the querystring should you have the need (i.e. form errors).
Not trying to knock you or the MD5 solution you offered. Just thought you made the two page solution sound scarier than it really is.
Ricky Morley 3 February 2005 23:36:03 [ permanent link ]
Richard Lynch <mailto:ceo@l-i-e.com>> on Thursday, February 03, 2005 11:26 AM said:>
A simple thing to do is to put an md5 hash into the POST data, then>> only do the insert if that md5 hash isn't already "used" when they>> hit refresh.
Thank you for your responses. One question: If I were to use the md5 hash method, what would be the best way to store used hashes? In a database? In a temporary file kinda thing? Thanks again.
Richard Lynch 4 February 2005 00:02:14 [ permanent link ]
Ricky Morley wrote:>> Richard Lynch <mailto:ceo@l-i-e.com>>> on Thursday, February 03, 2005 11:26 AM said:>>
A simple thing to do is to put an md5 hash into the POST data, then>>> only do the insert if that md5 hash isn't already "used" when they>>> hit refresh.>
Thank you for your responses. One question: If I were to use the md5 hash> method, what would be the best way to store used hashes? In a database? In> a temporary file kinda thing? Thanks again.
In a database with a datetime field.
Clear out anything older than a day or whatever in a cron job.
For a super busy site, you'd want to clear them out more often.
Or, to simplify matters, if you already have sessions, then do this:
<?php session_start();
//Check their FORM freshness, and only process fresh input, not re-loaded: $fresh = $_POST['fresh']; $used = isset($_SESSION['used']) ? $_SESSION['used'] : array(); if (isset($used[$fresh])){ echo "Ignoring re-posted data: $fresh<br />\n"; } else{ echo "INSERT INTO whatever (duplicate) VALUES ('$_POST[duplicate]')"; $used[$fresh] = TRUE; $_SESSION['used'] = $used; }
Make sure any test for a session time-out occurs BEFORE this test for 'fresh' data -- so they can't wait for the session to time-out, and then re-load, and get their duplicate "in" that way.
You could put most of the code to check for freshness in an include file, and use it on a zillion forms.
Just put the INPUT HIDDEN with NAME='fresh' and an MD5 in every form and be sure to: include 'freshness.inc'; before processing.
Or put it in a function you define in your globals.inc (or whatever gets loaded every page).
It's simple and browser-independent, so it doesn't matter if they hit back or not or re-load or their browser sends or doesn't send the signal needed for ignore_user_abort to work or...
Ricky Morley 4 February 2005 00:15:52 [ permanent link ]
You're wonderful. Thank you very much.
On Thu, 3 Feb 2005 13:02:14 -0800 (PST), Richard Lynch <ceo@l-i-e.com> wrote:
Ricky Morley wrote:>>> Richard Lynch <mailto:ceo@l-i-e.com>>>> on Thursday, February 03, 2005 11:26 AM said:>>>
A simple thing to do is to put an md5 hash into the POST data, then>>>> only do the insert if that md5 hash isn't already "used" when they>>>> hit refresh.>>
Thank you for your responses. One question: If I were to use the md5 >> hash>> method, what would be the best way to store used hashes? In a database? >> In>> a temporary file kinda thing? Thanks again.>
In a database with a datetime field.>
Clear out anything older than a day or whatever in a cron job.>
For a super busy site, you'd want to clear them out more often.>
Or, to simplify matters, if you already have sessions, then do this:>
<?php> session_start();>
//Check their FORM freshness, and only process fresh input, not > re-loaded:> $fresh = $_POST['fresh'];> $used = isset($_SESSION['used']) ? $_SESSION['used'] : array();> if (isset($used[$fresh])){> echo "Ignoring re-posted data: $fresh<br />\n";> }> else{> echo "INSERT INTO whatever (duplicate) VALUES ('$_POST[duplicate]')";> $used[$fresh] = TRUE;> $_SESSION['used'] = $used;> }>
Make sure any test for a session time-out occurs BEFORE this test for> 'fresh' data -- so they can't wait for the session to time-out, and then> re-load, and get their duplicate "in" that way.>
You could put most of the code to check for freshness in an include file,> and use it on a zillion forms.>
Just put the INPUT HIDDEN with NAME='fresh' and an MD5 in every form and> be sure to: include 'freshness.inc'; before processing.>
Or put it in a function you define in your globals.inc (or whatever gets> loaded every page).>
It's simple and browser-independent, so it doesn't matter if they hit > back> or not or re-load or their browser sends or doesn't send the signal > needed> for ignore_user_abort to work or...>
If it was only two pages, and there was only one header() re-direct, fine.>
But what ends up happening is you get in the habit of doing this all over> the place, and you have a mess of spaghetti logic spread over a hundred> files.
That is a problem with coding practices, not with the method used.
All you need to do is write a redirect() function used in all pages and call it instead of header(). Then you have one point to change if you need to make a change as you describe. The fact that someone did not do this does not mean the underlying method is a poor idea. It just means they didn't anticipate the need for application-specific code as part of the redirect operation.
Put another way, it's a common error to fail to build an abstraction layer for this type of low-level operation, but it doesn't mean using the low-level operation is a mistake. The error, if there is one (and I'd say there is in the scenario you describe) is in not noticing the need for an abstraction layer.
A simple thing to do is to put an md5 hash into the POST data, then>>> only do the insert if that md5 hash isn't already "used" when they>>> hit refresh.> Thank you for your responses. One question: If I were to use the md5 hash> method, what would be the best way to store used hashes? In a database? In> a temporary file kinda thing? Thanks again.
In a database with a datetime field.
Clear out anything older than a day or whatever in a cron job.
For a super busy site, you'd want to clear them out more often.
Or, to simplify matters, if you already have sessions, then do this:
<?php session_start();
//Check their FORM freshness, and only process fresh input, not re-loaded: $fresh = $_POST['fresh']; $used = isset($_SESSION['used']) ? $_SESSION['used'] : array(); if (isset($used[$fresh])){ echo "Ignoring re-posted data: $fresh<br />\n"; } else{ echo "INSERT INTO whatever (duplicate) VALUES ('$_POST[duplicate]')"; $used[$fresh] = TRUE; $_SESSION['used'] = $used; }
Make sure any test for a session time-out occurs BEFORE this test for 'fresh' data -- so they can't wait for the session to time-out, and then re-load, and get their duplicate "in" that way.
You could put most of the code to check for freshness in an include file, and use it on a zillion forms.
Just put the INPUT HIDDEN with NAME='fresh' and an MD5 in every form and be sure to: include 'freshness.inc'; before processing.
Or put it in a function you define in your globals.inc (or whatever gets loaded every page).
It's simple and browser-independent, so it doesn't matter if they hit back or not or re-load or their browser sends or doesn't send the signal needed for ignore_user_abort to work or...
If you would like to report an abuse of our service, such as a spam message, please . Если Вы хотите пожаловаться на содержимое этой страницы, пожалуйста .