php double form submit prevent - php

I would like to avoid the double form submit or unwanted submit when first time clicking the link to the form which outputs empty data.
The code I managed to find there , seems to prevent double or single empty form or previous form submit but it also prevents to submit the form when expected.
Main parts of the code as below, all parts on the same php file.
<?php
session_start();
$_SESSION['token'] = md5(session_id() . time());
?>
<!DOCTYPE HTML>
...
<form method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>" name="form_submitted">
<input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?>" >
<input type="checkbox" name="catexp[]" value="1">Input1
<input type="checkbox" name="catexp[]" value="2">Input2
<input type="checkbox" name="catexp[]" value="3">Input3
<input type="Submit" name="Submit" >
</form>
<?php
if (isset($_SESSION['token']))
{
if (isset($_POST['token']))
{
if ($_POST['token'] != $_SESSION['token'])
{
// double submit
}
else
{
// FORM PROCESSING HERE
}// else ($_POST['token'] == $_SESSION['token'])
} // if (isset($_POST['token']))
} // if (isset($_SESSION['token']))
?>
What needs to be done to make the form processing in the condition run?
Tkanks
Pascal

Setup session ID with user
Check if session ID is already in the database
Insert form if session is unique to database
I would recommend using a client-side check to reduce work required by the server. Use some JavaScript for this.

When first time form is submitted simply clear the $_SESSION['token']
if (isset($_SESSION['token']))
{
if (isset($_POST['token']))
{
if ($_POST['token'] == $_SESSION['token'])
{
unset($_SESSION['token']);
// do form processing
}
else
{
// double submit

Related

Two HTML forms submitted by PHP trigger each other

i've got 2 forms on one page, but when I press submit one the other is actioned.
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
Name: <input type="text" name="fname">
<input type="submit" name="getNameSubmit">
</form>
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// collect value of input field
if(isset($_REQUEST['fname']) && $_REQUEST['fname']!="")
{
$name = htmlspecialchars($_REQUEST['fname']);
if (empty($name)) {
echo "Hello dear user.";
} else {
echo "Hello $name";
}
}
}
?>
and
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
Full text: <input type="text" name="stringtoreplace" value="">
Word(s) to change: <input type="text" name="wordstochange" value="">
Change to: <input type="text" name="wordstoinput" value="">
<input type="submit" name="wordReplaceSubmit">
</form>
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// collect value of input field -- the if(isset) stops a pre-comparison that throws an E_NOTICE level error
if(isset($_REQUEST['stringtoreplace']) && $_REQUEST['stringtoreplace']!="")
{
$stringoutput = htmlspecialchars($_REQUEST['stringtoreplace']);
}
if(isset($_REQUEST['wordstochange']) && $_REQUEST['wordstochange']!="")
{
$tochange = htmlspecialchars($_REQUEST['wordstochange']);
}
if(isset($_REQUEST['wordstoinput']) && $_REQUEST['wordstoinput']!="")
{
$changeto = htmlspecialchars($_REQUEST['wordstoinput']);
}
if (empty($stringoutput)) {
echo "Please enter your text and the words to change.";
} else {
echo str_replace($tochange, $changeto, $stringoutput);
}
}
?>
How can I get one to action without triggering the other? The function and placement isn't a factor here, I'm just doing some practice, but would be nice ton understand why this happens and how to resolve.
<?php echo $_SERVER['PHP_SELF'];?> gives the current URL, so because they're in the same page, it causes the problem. You can check this on inspecting the page Ctrl + Shift + i then clicking on Elements on Chrome.
One solution might be to give different URLs to both the forms or use parameters on post request. Eg.- <?php echo $_SERVER['PHP_SELF'].'?form=form1';?> & <?php echo $_SERVER['PHP_SELF'].'?form=form2';?>
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if(isset($_GET['form'])){
if($_GET['form'] == 'form1'){
//code for form1
}else{
//code for form2
}
}
}
Ok, let's start on why this is happening.
The action parameter of an HTML tells the browser which URL to send the POST request with the form data. In your case, it's $_SERVER['PHP_SELF'], which is the current PHP script. You use the same for both forms.
When one of the forms is submitted, your PHP script gets called, and all the PHP in the script gets executed. The first part (the one after the first form) checks if ($_SERVER["REQUEST_METHOD"] == "POST"), decides that yes, it was a POST request, and tries to proceed. After that, the second part (the one after the second form), uses the exact same check, decides that yes, it was a POST request, and tries to proceed too.
Ideally, it would be cleaner to have two different pages to process two different forms; but if you prefer to keep all in the same page, you have a couple of different options to distinguish between the two.
1) Use a different query parameter in the action attribute for each form, as suggested by #sauhardnc. The forms would look like:
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>?form=form1">
...
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>?form=form2">
while the PHP side would do something like
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if ($_GET['form'] == 'form1') {
// code for form1
} else {
// code for form2
}
}
2) Use a different input in each form. The forms would look like:
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
...
<input type="hidden" name="form" value="form1">
</form>
...
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
...
<input type="hidden" name="form" value="form2">
</form>
while the PHP side would do something like
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if ($_REQUEST['form'] == 'form1') {
// code for form1
} else {
// code for form2
}
}

php prevent form resubmission using sessions

So I am trying to prevent form resubmission using sessions
and this is my code :
<?php
session_start();
if(isset($_GET['unid']))
{
if ($_GET['unid']==$_SESSION["uid"])
{
echo "Form is Submited do something";
}
else
{
echo "no you can't do that";
}
}
$unid = md5(uniqid());
$_SESSION["uid"] = $unid;
?>
<form method="GET">
<input name="name" value="test">
<input name="unid" value="<?php echo $unid;?>">
<input type="submit">
and it works ...but if the user opens another tab then it will break so how can I fix it ?
I'm not sure about this but may be assigning a new global session variable will work, say $_SESSION['checkSub']. So once the form is submitted, set it to 1 or true and only let form submission if it isn't 1 or false.
You can check to see if the unid is set in the session before generating a new unique id. See updated code below:
<?php
session_start();
if(isset($_GET['unid']))
{
if (isset($_SESSION['unid']) && $_GET['unid']==$_SESSION['unid'])
{
//form has been submitted with matching unid - process it as needed
unset($_SESSION['unid']);
}
else
{
// Form was resubmitted or some other logic error
}
}
$unid = ''; //declare here for good scope
if (isset($_SESSION["unid"])) {
$unid = $_SESSION["unid"];
}
else {
$unid = md5(uniqid());
$_SESSION["unid"] = $unid;
}
?>
<form method="GET">
<input name="name" value="test">
<input name="unid" value="<?php echo $unid;?>">
<input type="submit">
Rather than using form method GET, try to use POST. It will work for you. The $_POST array will only have data in it when form is submitted, so you should not have to use the session to know whether form is submitted or not.

Two PHP pages to pass form data to the same target file

I have a Customer Details PHP page. To get to this page, the user either signs up with new details on signup.php or they log in on login.php.
Ive been told the best way to submit data and be redirected to the correct page is to use action="details.php" in the form, and then at the start of the details.php file use the values from the $_POST array to populate my SQL database.
However, I need to do the same sort of thing with the login.php code, so at the top of details.php there will be the code to enter the form data from signup.php and the verifying code from login.php.
Surely there is a way of doing the data submission directly from signup.php so there isnt two sets of PHP in the details.php file? If not how do i differentiate so that login only uses the login code and signup uses the submit code?
Common practice is to have PHP check for form data+possible redirect and after that form print
Example: (my common usage)(i merged login&signup into one file)
<?php
$error = "";
if( !empty($_POST['signup']) ){
//do signup
//$signup = assign true/false whether sign up was successfull or not
if( !$signup ){ //if signup wasnt successfull generate error
$error = "Sign up error.";
}
}
if( !empty($_POST['login']) ){
//do login
//$login = assign true/false whether login was successfull or not
if( !$login ){ //if login wasnt successfull generate error
$error = "Log in error.";
}
}
if( empty($error) ){
//there were no errors
header("Location: details.php"); //redirect to details.php
exit(); //send nothing else!
}
?>
<div class="error"><?php if(!empty($error)){ echo htmlspecialchars($error); /*escape*/ } ?></div>
<form action="#" method="POST">
<input type="hidden" name="signup" value="yes">
<!-- ...some other input fields... -->
<button type="submit">Sign Up</button>
</form>
<br>
<form action="#" method="POST">
<input type="hidden" name="login" value="yes">
<!-- ...some other input fields... -->
<button type="submit">Log In</button>
</form>
You could set a hidden field on each page as below:
<input type=hidden name='referrerpage' value='signup'>
AND
<input type=hidden name='referrerpage' value='login'>
and do:
if ($_POST['referrerpage']=='signup'){
//do this
} else{
//do this
}

php two self submitting forms on one page

I have a webpage form that submits to itself to carry out php action. I want to add a second form to this same webpage that is capable of self submit as well but I am not having any luck finding a working solution for my setup. Here is what my webpage looks like.
First, it checks to see if the page has already been submitted, and if it has, it redirects elsewhere.
if($_SERVER['REQUEST_METHOD'] == "POST") {
header("Location: viewcustomers.php");
}
Next, the form itself.
<form id="addCustomer" method="POST" action=""> ..stuff.. </form>
Then, finally my form action.
if('POST' == $_SERVER['REQUEST_METHOD']) {
..phpstuff..
}
How could I adjust this form action (or add another) to differentiate between two different forms?
Thanks.
Easy!
<?php
if(isset($_POST['action']) && $_POST['action'] == 'form1') {
// Form 1
} else if(isset($_POST['action']) && $_POST['action'] == 'form2') {
// Form 2
}
?>
<form action="#" method="post">
<input type="hidden" name="action" value="form1" />
</form>
<form action="#" method="post">
<input type="hidden" name="action" value="form2" />
</form>

Checking if radiobutton is checked using POST

I'm trying to redirect the user to another webpage depending on which radio button they have checked.
Here is the relevant code:
<form action="sample.php" method="post">
<input name="survey" type="radio" value="Yes" /> Yes
</br>
<input name="survey" type="radio" value="No" /> No
</form>
<?
if ($_POST['survey'] == "Yes")
{
header('Location: http://localhost/survey.php');
}
else if ($_POST['survey'] == "No")
{
header('Location: http://localhost/survey.php');
}
?>
For some reason or another I get an error within my if statement. That does not recognize 'survey' as a valid index. How Am I failing to do something to link my form to the php code?
Your warning is caused by the fact that when you load the page using GET (a normal request), $_POST['survey'] is not set.
You could change your conditions by adding a isset($_POST['survey'] ) && in front of every time you use it or you could put the whole code in a block that checks if a post was made like:
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
if ($_POST['survey'] == "Yes")
{
header('Location: http://localhost/survey.php');
}
else if ($_POST['survey'] == "No")
{
header('Location: http://localhost/survey.php');
}
}
else
{
// output html
}
Either way you would have to put this in front of your html as you cannot use header if the headers have already been sent (stuff has already been outputted to the browser).
Think about how forms work:
The first time you visit your page, the form is not submitted. Yet, your if/else is acting as though it were. That's what's causing the error - $_POST['survey'] doesn't exist the first time.
Write your scripts properly - do all potential form processing before rendering HTML:
<?php
if (isset($_POST['submit'])) {
// handle the form
}
?>
<!doctype html>
<html>
<head>
<title>Blah</title>
</head>
<body>
<!-- code -->
</body>
</html>
That will allow you to check if you've submitted the form to itself, and potentially use a header() to redirect the user without running into those pesky "Headers already sent" errors.
Try a simple print_r() statement to see if $_POST has any contents at all. Put this at the top of the page:
print_r($_POST);
Also, be sure that you're loading the results page via the form. If you just type the URL of the page it will not have any POST data sent with it.
The first time you load your file sample.php there is no POST data, therefore there's no index 'survey'.
You need to nest it in another if statement or modify it the following:
<form action="sample.php" method="post">
<input name="survey" type="radio" value="Yes" /> Yes
</br>
<input name="survey" type="radio" value="No" /> No
</form>
<?
if (isset($_POST) && $_POST['survey'] == "Yes")
{
header('Location: http://localhost/survey.php');
}
else if (isset($_POST) && $_POST['survey'] == "No")
{
header('Location: http://localhost/survey.php');
}
?>
I am using a different php file for the checking.
<html>
<body>
<form action="another.php" method="POST">
<label>You are: </label> Male <input type="radio" name="male"> Female <input type="radio" name="female"><br/><br/>
<input type="submit" name="submit" value="GO">
</body>
</html>
*****another.php******
<?php
if (isset($_POST['submit']))
{
if(empty($_POST['male']) && empty($_POST['female']))
{echo "select gender";}
elseif (empty($_POST['female'])) //means Male is checked
{
$gend="Male";
echo $gend;
}
elseif(empty($_POST['male'])) //Means Female is checked
{
$gend="Female";
echo $gend;
}
elseif(empty($_POST['male']) || empty($_POST['female'])== false) //Not required if you can disable one when another is checked
{echo"please select only one";}
}
?>

Categories