[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

prevent multi form post

Posted on 2011-05-04
8
Medium Priority
?
340 Views
Last Modified: 2012-06-21
I'm trying to prevent a multi form post but don't seem like I've got it.


<?php
$domainName = $_SERVER['HTTP_HOST'];
$voucherCode = $_GET['v'];
if($voucherCode == "")
{
header("location:index.php");
}
//declare variable and set to empty
$message = "";
//db settings
$host="local"; // Host name 
$username="admin"; // Mysql username 
$password="admin!"; // Mysql password 
$db_name="dbtest"; // Database name 
$tbl_name="vouchers"; // Table name 
//get postback
if(isset($_POST['btnSubmit']))
{
	//get form data and clean it
    $firstName = check_input($_POST['txtbxfirstName']);
    $lastName = check_input($_POST['txtbxlastName']);
    $address1 = check_input($_POST['txtbxaddress1']);
    $address2 = $_POST['txtbxaddress1'];
    if($address2 != "")
    {
    	$address2 = check_input($_POST['txtbxaddress2']);
    }
    $city = check_input($_POST['txtbxcity']);
    $state = check_input($_POST['ddlstate']);
    $zip = check_input($_POST['txtbxzip']);
	$phone = check_input($_POST['txtbxprimaryphone']);
	$email = check_input($_POST['txtbxemailaddress']);
	$vouchercode = $_POST['hvvc'];
	$dateredeemed = date("m/d/y",time());
	
    //search for the value and if redeemed
    searchTable($vouchercode);
	//load data
	loadData($firstName,$lastName,$address1,$address2,$city,$state,$zip,$phone,$email,$vouchercode,$dateredeemed,$domainName);	
}
//run process to clean form data
function check_input($data)
{
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
}
//search for data
function searchTable($data)
{
	//global variables
	global $message,$host, $username, $password,$db_name,$tbl_name;

	mysql_connect("$host", "$username", "$password")or die("cannot connect ".mysql_error()); 
	mysql_select_db("$db_name")or die("cannot select DB - ".mysql_error()); 
	$query = "select vouchercode from $tbl_name where vouchercode = '$data' ";
	$result = mysql_query($query)or die(mysql_error());
	if (mysql_num_rows($result))
	{
	    //$message = "This is voucher has been redeemed.";
	    header("location:index.php");
	}
}
//load data
function loadData($firstName,$lastName,$address1,$address2,$city,$state,$zip,$phone,$email,$vouchercode,$dateredeemed,$domainName)
{
	//global variables
	global $domainName, $message, $host, $username, $password,$db_name,$tbl_name;
	mysql_connect("$host", "$username", "$password")or die("cannot connect ".mysql_error()); 
	mysql_select_db("$db_name")or die("cannot select DB - ".mysql_error());

	try
	{
		mysql_query("insert into $tbl_name (firstname,lastname,address1,address2,city,state,zip,primaryphone,emailaddress,vouchercode,dateredeemed,domain) values ('$firstName','$lastName','$address1','$address2','$city','$state','$zip','$phone','$email','$vouchercode','$dateredeemed','$domainName')");
	}
	catch (Exception $e)
	{
		header("location:error.php");
	}
	
	try
	{
		mysql_query("update vouchercodes set redeemed = 'Y' where vouchercode = '$vouchercode'");
	}
	catch (Exception $e)
	{
		header("location:error.php");
	}
	
	$message = "Your voucher has been entered into our systems and is pending review. Thank you.";
	header("location:thankyou.php?fn=$firstName&ln=$lastName&msg=$message");
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Untitled 1</title>
<script type="text/javascript">
//validate the form
function ValidateForm()
{
	//validate txtbxfirstName
	if(document.vcodeform.txtbxfirstName.value == "")
   	{ 
    	alert('You must indicate your first name.') 
      	document.vcodeform.txtbxfirstName.focus(); 
      	return false; 
   	}
   	//validate txtbxlastName
	if(document.vcodeform.txtbxlastName.value == "")
   	{ 
    	alert('You must indicate your last name.') 
      	document.vcodeform.txtbxlastName.focus(); 
      	return false; 
   	}
   	//validate txtbxaddress1
	if(document.vcodeform.txtbxaddress1.value == "")
   	{ 
    	alert('You must indicate your address 1.') 
      	document.vcodeform.txtbxaddress1.focus(); 
      	return false; 
   	}
   	//validate txtbxaddress2
	//if(document.vcodeform.txtbxaddress2.value == "")
   	//{ 
    	//alert('You must indicate your address 2.') 
      	//document.vcodeform.txtbxaddress2.focus(); 
      	//return false; 
   	//}
   	//validate txtbxcity
	if(document.vcodeform.txtbxcity.value == "")
   	{ 
    	alert('You must indicate your city.') 
      	document.vcodeform.txtbxcity.focus(); 
      	return false; 
   	}
	//validate txtbxzip
	if(document.vcodeform.txtbxzip.value != "")
   	{
		if(checkZip(document.vcodeform.txtbxzip.value))
	   	{
			  // 
	   	}
	   	else
	   	{
		  	alert('Your Zip Code is in an incorrect format.') 
		  	document.vcodeform.txtbxzip.focus(); 
		  	return false; 
	   	}
   	}
   	else
   	{ 
      	alert('You must indicate your Zip Code.') 
      	document.vcodeform.txtbxzip.focus(); 
      	return false; 
   	}
	//valiate txtbxprimaryphone
	if(document.vcodeform.txtbxprimaryphone.value != "")
   	{ 
   		if (checkPhone(document.vcodeform.txtbxprimaryphone.value))
		{
			//
		}
		else
		{
			alert('Your Phone Number is in an incorrect format.') 
			document.vcodeform.txtbxprimaryphone.focus(); 
			return false;   
		}
   	}
   	else
   	{
		if(document.vcodeform.txtbxprimaryphone.value == "")
		   	{
		      	alert('You must indicate your Phone Number.') 
		      	document.vcodeform.txtbxprimaryphone.focus(); 
		      	return false; 
		   	}
	}
	//validate txtbxemailaddress
   	if(document.vcodeform.txtbxemailaddress.value != "")
   	{
		if(checkEmail(document.vcodeform.txtbxemailaddress.value))
	   	{
		  // 
	   	}
	   	else
	   	{
      		alert('Your Email Address is in an incorrect format.') 
      		document.vcodeform.txtbxemailaddress.focus(); 
      		return false; 
	   	}
   	}
   	else
   	{
		if(document.vcodeform.txtbxemailaddress.value == "")
	   	{ 
			alert('You must indicate your Email Address.') 
	      	document.vcodeform.txtbxemailaddress.focus(); 
	      	return false; 
	   	}
	}
//end
return true; 
}
//validate zip code
function checkZip(str) 
{
	var zip2 = /^\d{5}$/; 
	if (str.match(zip2)) {
   		return true;
 	} else {
 		return false;
 	}
}
//validate phone format
function checkPhone(str) 
{
	var phone2 = /^(\+\d)*\s*(\(\d{3}\)\s*)*\d{3}(-{0,1}|\s{0,1})\d{2}(-{0,1}|\s{0,1})\d{2}$/; 
	if (str.match(phone2)) {
   		return true;
 	} else {
 		return false;
 	}
}
//validate email format
function checkEmail(str) 
{
	var email2 = /^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/; 
	if (str.match(email2)) {
   		return true;
 	} else {
 		return false;
 	}
}
</script>
</head>
<body onload="document.vcodeform.txtbxfirstName.focus();">
<form name="vcodeform" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
 <table cellpadding="0" cellspacing="0" style="width: 25%">
	<tr>
		<td colspan="2">Redeem your Voucher</td>
	</tr>
	<tr>
		<td colspan="2">Voucher Code: <?php echo $voucherCode; ?></td>
	</tr>
	<tr>
		<td>First Name</td>
		<td><input name="txtbxfirstName" type="text" id="txtbxfirstName" tabindex="1"></td>
	</tr>
	<tr>
		<td>Last Name</td>
		<td><input name="txtbxlastName" type="text" id="txtbxlastName" tabindex="2"></td>
	</tr>
	<tr>
		<td>Address 1</td>
		<td><input name="txtbxaddress1" type="text" id="txtbxaddress1" tabindex="3"></td>
	</tr>
	<tr>
		<td>Address 2</td>
		<td><input name="txtbxaddress2" type="text" id="txtbxaddress2" tabindex="4"></td>
	</tr>
	<tr>
		<td>City</td>
		<td><input name="txtbxcity" type="text" id="txtbxcity" tabindex="5"></td>
	</tr>
	<tr>
		<td>State</td>
		<td>
		<select name="ddlstate" size="1" tabindex="6">
        <option value="AK">AK</option>
        <option value="AL">AL</option>
        <option value="AR">AR</option>
        <option value="AZ">AZ</option>
        <option value="CA">CA</option>
        <option value="CO">CO</option>
        <option value="CT">CT</option>
        <option value="DC">DC</option>
        <option value="DE">DE</option>
        <option value="FL">FL</option>
        <option value="GA">GA</option>
        <option value="HI">HI</option>
        <option value="IA">IA</option>
        <option value="ID">ID</option>
        <option value="IL">IL</option>
        <option value="IN">IN</option>
        <option value="KS">KS</option>
        <option value="KY">KY</option>
        <option value="LA">LA</option>
        <option value="MA">MA</option>
        <option value="MD">MD</option>
        <option value="ME">ME</option>
        <option value="MI">MI</option>
        <option value="MN">MN</option>
        <option value="MO">MO</option>
        <option value="MS">MS</option>
        <option value="MT">MT</option>
        <option value="NC">NC</option>
        <option value="ND">ND</option>
        <option value="NE">NE</option>
        <option value="NH">NH</option>
        <option value="NJ">NJ</option>
        <option value="NM">NM</option>
        <option value="NV">NV</option>
        <option value="NY">NY</option>
        <option value="OH">OH</option>
        <option value="OK">OK</option>
        <option value="OR">OR</option>
        <option value="PA">PA</option>
        <option value="RI">RI</option>
        <option value="SC">SC</option>
        <option value="SD">SD</option>
        <option value="TN">TN</option>
        <option value="TX">TX</option>
        <option value="UT">UT</option>
        <option value="VA">VA</option>
        <option value="VT">VT</option>
        <option value="WA">WA</option>
        <option value="WI">WI</option>
        <option value="WV">WV</option>
        <option value="WY">WY</option>
        </select>
		</td>
	</tr>
	<tr>
		<td>Zip</td>
		<td><input name="txtbxzip" type="text" id="txtbxzip" tabindex="7"> Ex: xxxxx</td>
	</tr>
	<tr>
		<td>Primary Phone</td>
		<td><input name="txtbxprimaryphone" type="text" id="txtbxprimaryphone" tabindex="8"> Ex: (xxx) xxx-xxxx</td>
	</tr>
	<tr>
		<td>Email Address</td>
		<td><input name="txtbxemailaddress" type="text" id="txtbxemailaddress" tabindex="9"> Ex: xxx@xxx</td>
	</tr>
	<tr>
		<td colspan="2">
		<input name="btnSubmit" type="submit"  id="btnSubmit" onclick="return ValidateForm()" value="Submit" tabindex="10">
		<input type="hidden" id="hvvc" name="hvvc" value="<?php echo $voucherCode; ?>" />
		</td>
	</tr>
	<tr>
		<td colspan="2">
				<?php 
		  //print form data
		      echo $message; 
		?>
		</td>
	</tr>
</table>
</form>
 </body>

</html>

Open in new window

0
Comment
Question by:vicomin
  • 4
  • 3
8 Comments
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 35694284
Wow, over 300 lines of code for us to sift through...

Can you please restate the question and tell us what you mean by multi form post?  Thanks, ~Ray
0
 
LVL 12

Expert Comment

by:Mohamed Abowarda
ID: 35694533
In javascript, create public boolean, when the user submit the form set it to TRUE, you can do that by changing form onsubmit.

Everytime the user submit the form, check if the variable is FALSE, if not ignore the submit request, there is already one in progress.
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 35694598
If the problem definition is what I think it might be (client submits the form twice with the same data) I think I might want to do the validation on the server side of things.  Clients can, and do, turn off JavaScript.  Hackers can, and do, post toxic stuff directly into action scripts.  For that reason alone, most security experts advise that any client-side security measure is essentially meaningless and must be handled on the server.  That is not to say that client-side data validation has no place in web design.  On the contrary, it may make for very nice forms.  But you will still have to validate all of the information after you get it on the server and it is completely outside of the client's hands.

In any case, when the author of the question answers what is meant by "multi form post?" we will be better equipped to produce a good answer and an example of a script that can be adapted to suit the needs.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 12

Expert Comment

by:Mohamed Abowarda
ID: 35694604
@Ray_Paseur: You just understood the question from my solution! :)
0
 
LVL 111

Accepted Solution

by:
Ray Paseur earned 2000 total points
ID: 35694830
just understood the question - Yes, that may be true!  Here is how I have dealt with the issue in the past.  Example available on my server here:
http://www.laprbass.com/RAY_multi_submit.php
<?php // RAY_multi_submit.php
error_reporting(E_ALL);


// PREVENT MULTIPLE SUBMISSIONS DUE TO REPEATED CLICKS ON SUBMIT BUTTON
// EXAMPLE:
//    if ( multi_submit() )
//    {
//       handle error
//    }
//    else
//    {
//       normal processing
//    }



// ALWAYS START SESSION ON EVERY PAGE
session_start();


function multi_submit($type="post")
{
    // MAKE THE FUNCTION WORK FOR EITHER GET OR POST SUBMITS
    $input_array = (strtoupper($type) == "GET") ? $_GET : $_POST;

    // GATHER THE CONTENTS OF ALL THE SUBMITTED FIELDS AND MAKE A MESSAGE DIGEST
    $string = "";
    foreach ($input_array as $val) { $string .= $val; }
    $string = md5($string);

    // IF THE SESSION VARIABLE IS NOT SET, THIS IS NOT A MULTI-SUBMIT
    if (!isset($_SESSION["_multi_submit"]))
    {
        // SAVE THE SUBMITTED DATA MESSAGE DIGEST
        $_SESSION['_multi_submit'] = $string;
        return FALSE;
    }

    // IF THE SESSION DATA MATCHES THE MESSAGE DIGEST, THIS IS A MULTI-SUBMIT
    if ($_SESSION['_multi_submit'] === $string)
    {
        return TRUE;
    }
    else
    {
        // SAVE THE MESSAGE DIGEST
        $_SESSION['_multi_submit'] = $string;
        return FALSE;
    }
}

// SHOW HOW THIS IS DONE
if (!empty($_POST))
{
    if (multi_submit())
    {
        die("ALREADY GOT THAT");
    }
}
// END OF PHP - PUT UP THE FORM
?>
<form method="post">
ENTER SOMETHING, THEN REENTER IT
<input name="foo" />
<input type="submit">
</form>

Open in new window

0
 

Author Comment

by:vicomin
ID: 35710632
multi - meaning that the user resubmits the web form -- send once okay but more than once is what i want to prevent -- guess that is double post?
0
 
LVL 12

Expert Comment

by:Mohamed Abowarda
ID: 35711119
In Experts Exchange, when you submit a question/comment, the "submit" button only accept the first click, if you double clicked, it will ignore the second click, and you can exactly do the same by using boolean which will check whether the button already clicked or not.

Look at my initial post, it should help you with you are trying to do.

You can also do some server side coding to prevent that by adding random hash key generated on page load by PHP, the hash key will be sent on submit by hidden input inside the form as the following:
<input type="hidden" name="formHash" value="THE_RANDOM_HASH_KEY_WILL_BE_HERE">

Open in new window


This hash key will be stored into session each time the user submit the form.

Each time the server receive the form, it will check if the hash is the same as the last one, in the case that the user submitted the form twice, the hash key will be submitted twice also, so the server will know that this is duplication and ignore the duplication request as the first request is still progress.
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 35711784
... the user resubmits the web form -- send once okay but more than once is what i want to prevent
The discussion and code example at ID:35694830 shows exactly how to do this.  I use it all the time in my own web sites.  You do not need to add any hash key to the form; the hash is made from the submitted data, as shown in lines 27-30 of the demonstration script.

You cannot really prevent the client machine from resubmitting a form, any more than you can prevent hackers from attacking your action script, but you can detect duplicate submissions and you can filter the input data.  Both of those are important in online applications where, from a security perspective, all external input must be considered to be an attack vector.  As the security mantra goes, "Accept Only Known Good Values."

Anyway, thanks for clarifying the question.  You can test that script on my server or install it and run it on your own server to see how it implements the solution.  Best regards, ~Ray
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

3 proven steps to speed up Magento powered sites. The article focus is on optimizing time to first byte (TTFB), full page caching and configuring server for optimal performance.
The title says it all. Writing any type of PHP Application or API code that provides high throughput, while under a heavy load, seems to be an arcane art form (Black Magic). This article aims to provide some general guidelines for producing this typ…
The viewer will learn how to count occurrences of each item in an array.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
Suggested Courses
Course of the Month18 days, 12 hours left to enroll

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question