Re: Clearing POST variable on page refresh

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.

-- 
Some people have a "gift" link here.
Know what I want?
I want you to buy a CD from some starving artist.
http://cdbaby.com/browse/from/lynch
Yeah, I get a buck. So?

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux