Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

preventing duplicate records from refresh 1

Status
Not open for further replies.

foxphpbomb

Programmer
Apr 10, 2007
29
US
I would like to know if there is some code that I can use to prevent a page that has been loaded in which the values from a form are inserted in a db, from entering a duplicate record when the refresh button is hit,
 
Create a Session variable the first time its submitted, with a unique id or something, and check for it on subsequent runs, if it exists, then don't follow up with the insert or update to the DB.


something like:
Code:
session_start();
if(!isset($_SESSION['uniqueid'])){
$_SESSION['uniqueid']="someuniqueid";
[green]\\and perform updates. or insterts[/green]
}
else{
[green]\\issue message of duplicate entries and redirect.[/green]
}


----------------------------------
Ignorance is not necessarily Bliss, case in point:
Unknown has caused an Unknown Error on Unknown and must be shutdown to prevent damage to Unknown.
 
Hi

Another common practice is to redirect after registering the [tt]form[/tt] data. That way the user will not refresh the page with the [tt]form[/tt].

I usually do it somehow like below. So the PHP script to which the [tt]form[/tt] data is submitted displays its document only if there are errors. If the data is correct, it saves it than immediately redirects to a simple page which does not handle data and can be refreshed without consequences.
Code:
<?php
[b]for[/b] ($_POST as $field=>$value) {
  [gray]// check the data[/gray]
}
[b]if[/b] ($error_count==0) {
  [gray]// save the data[/gray]

  header([i]"Location: thank_you.htm"[/i]);
  [b]return[/b];
}
?>
<html>
<head>
<title>You have <?php echo $error_count; ?> error(s) in the form data</title>
</head>
[gray]<!-- ... -->[/gray]
Note that this is not 100% safe solution. If the visitor steps back in the browser history, will be able to resubmit.

Also vacunita's check can be avoided by simply deleting the session cookie. ( A minor correction could be to add the session ID to the [tt]form[/tt] in a [tt]hidden input[/tt]. )

So all simple solutions avoids only accidental resubmission and not the malefic ones.

Feherke.
 
I personally use a variation on vacunita's method.

i store the session variable both on the server and in the form as a hidden field. on submission i test that the hidden field and the session var are equal. if they are, i unset the session variable and allow the transaction. If anything else then don't process the data.

this method can be used to stop back button refreshes and also to prevent spam robots from hitting a guestbook/chatroom/contact form etc.

 
each genuine form submission and redisplay would regenerate the uid. here's a mock-up of what I use
Code:
<?php
session_start();
if (isset($_POST['submit'])){
	processForm();
}else{
	displayForm();
}
function testUnique(){
	if (!isset($_SESSION['uid'])) return false;
	if (!isset($_POST['uid'])) return false;
	if (trim($_POST['uid']) !== $_SESSION['uid']) return false;
	return true;
}
function generateUID(){
	if (isset($_SESSION['uid'])){
		return $_SESSION['uid'];
	}else{
		$_SESSION['uid'] = uniqid("test_", true);
		return $_SESSION['uid'];
	}
}
function displayForm($msg=''){
	$msg = !empty($msg)?"<legend>$msg</legend>":'';
	$uid = generateUID();
	$field = isset($_POST['field']) ? $_POST['field'] : '';
	echo <<<HTML
<form method="post" action="{$_SERVER['PHP_SELF']}" >
	<fieldset style="width:40%;">
	$msg
	<input type="hidden" name="uid" value="$uid" />
	<input type="text" name="field" value="$field" />
	<input type="submit" name="submit" value="submit" />
	</fieldset>
</form>
HTML;
}
function processForm(){
	if (testUnique()){
		//processform
		//if form processes correctly kill the session vars
		killVars();
		displayForm("success");
	} else {
		//you may want to do something else here
		killVars();
		displayForm("refresh");
	}
	
}

function killVars(){
	unset($_SESSION['uid']);
	unset($_POST);
}
?>
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top