RE: [PHP] Clearing POST variable on page refresh
| From: | Beauford | Date: | Mon, 18 Dec 2006 22:37:27 +0000 |
| Subject: | RE: [PHP] Clearing POST variable on page refresh | ||
| References: | 1 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-245984@lists.php.net to get a copy of this message | ||
> -----Original Message-----
> From: Richard Lynch [mailto:ceo@l-i-e.com]
> Sent: December 18, 2006 3:46 PM
> To: Beauford
> Cc: PHP
> Subject: Re: [PHP] Clearing POST variable on page refresh
>
> On Sun, December 17, 2006 4:59 pm, Beauford wrote:
> > I have a page with a form on it which posts to itself. The
> problem is
> > when someone refreshes the page it enters the data into the
> DB again.
> > How do I clear these variables so that doesn't happen. I tried the
> > unset function, but no luck. I really don't want to use sessions or
> > cookies as this is just a simple little page, but still, it has to
> > work right.
>
> The redirect solution has several "gotchas"
>
> It tends to mess up the "back" button, which is annoying to
> some users. (Okay, maybe that's just me.)
>
> It's possible for an impatient user to hit "Back" and "Stop"
> fast enough to re-submit the data anyway, in some browsers,
> so it doesn't solve the problem 100%, really.
>
> A header() to redirect chews up HTTP connections, which can
> be problematic on a heavy-traffic site, because it has to
> send the 302 to the browser, which then has to send back
> another HTTP request to the server to get the "new" page. So
> you double your traffic load and number of Apache children
> needed to provide the feature-set of this page. On a
> much-visited page on a busy server, that can be a real issue,
> instead of the non-issue it usually is. YMMV NAIAA
>
>
> Embedding a "token" in the FORM, and tracking that "token" as
> used in a session or db is what I prefer, personally.
>
> Since you don't want to use sessions, you can simply have one
> more table in your DB:
>
> create table used_token (
> token char(32) unique not null primary key,
> whatdate date
> );
> create index used_token_whatdate_index on used_token(whatdate);
>
> Then in your original FORM part of the script:
> <form action="<?php echo $_SERVER['PHP_SELF']?>"
> method="post">
> <input type="hidden" name="token" value="<?php echo
> md5(uniqid(rand(), true)?>" />
> Rest of form here
> </form>
>
> In the processing section:
> <?php
> $token = $_POST['token'];
> if (!preg_match('/[0-9a-g]{32}/i', $token)) die("Bad Guy");
> $query = "select count(*) from used_token where token = '$token'";
> $used = mysql_query($query, $connection) or die("Database Offline" .
> error_log(mysql_error($connection));
> $used = mysql_result($used, 0, 0);
> if (!$used){
> //insert form contents to DB (your existing code goes here)
> $query = "insert into used_token(token, whatdate)
> values('$token', now())";
> mysql_query($query, $connection) or die("Database Offline" .
> error_log(mysql_error($conection));
> }
> else{
> //do whatever you want to do with a re-submission,
> possibly nothing
> }
> ?>
>
>
> Then you'll want a cron job to clear out any token in
> used_token where the whatdate field is, say, a week or more
> old. Less than a week on an ultra busy server.
>
> <?php
> //cron job to clear out old data
> $query = "delete from used_token where whatdate <
> date_sub(now(), interval 1 week)";
> mysql_query($query, $connection) or
> die(mysql_error($connection)); ?>
>
> There is a 1 in a billion chance that two users could get the
> same token, but you can play games with that as well to
> guarantee uniqueness.
>
> --
Hmm. I was thinking more of a one liner that would just clear the memory
buffer of these variables, but it seems this is a little more involved than
I anticipated. And it's not that I didn't want to use sessions, I just
didn't want the extra work - but what you suggested above is way more work
than sessions. So now I've just used a simple session. If it's true, don't
add the user, if false add user. Still not exactly what I want, but will do
until I find something better.
This is most likely not a php thing, but would there be a way to refresh the
page, fooling the browser into thinking it's being freshly loaded?
Thanks to all.