表单提交后取消设置过帐变量


Unset post variables after form submission

有办法做到这一点吗?基本上,如果有人在提交了一次表格后按下刷新键,我不希望再次提交表格。在这种情况下,浏览器会询问您是否要再次提交表单。在这种情况下,unset($_POST['username'])会有什么帮助吗?

post/redirect/get是一个不错的选择,正如一些海报已经提到的那样。

我可以想到的另一种方法是在dostuff.php页面中设置一个会话,以表明发布已经完成。每次检查此会话var,查看是否由于页面刷新而再次加载页面。

<?php
    session_start();
    if(isset($_SESSION['indicator'])) 
    {
        /*
        dont do anything because session indicator says 
        that the processing was already done..
        you might want to redirect to a new url here..          
        */
    }   
    else
    {
        /*
        first set session indicator so that subsequent 
        process requests will be ignored
        */
        $_SESSION['indicator'] = "processed"; 
        //process the request here..
    }
    ?>

在重定向到的页面中,取消设置会话var,以便可以重新提交表单,使其成为新的post操作。这将允许新的表单发布,但由于页面刷新而阻止发布操作

使用中间页面执行操作,然后重定向。

例如:

mypage.php-->表单为的页面

dostuff.php-->接收表单数据并进行操作,然后重定向到任何其他页面。

要进行重定向:
将这一行放在"dostuff.php"的顶部:header("Location: mypage.php");

您具体面临的问题可以(也应该)通过Post/Rerect/Get解决。在php端取消设置_POST是无效的,因为问题是它是一个单独的请求。

您还必须处理双击提交按钮的问题。您可以在客户端解决此问题,方法是在单击按钮后禁用表单提交,或者在表单中放入随机令牌并将该令牌存储在会话中。令牌将只被接受一次(会话跟踪令牌是否已发布)。

这里有一个很好的方法,可以防止用户两次提交相同的数据,这也可以防止页面在重新加载时向数据库添加相同的记录。

// First IF
if ($_SESSION['dup_comment_body'] == $_POST['comment_body']) { 
    echo 'You already entered that.';
} else {
    // Second IF
    if ($_POST['comment_body']) {
        // Run your query here
    $_SESSION['dup_comment_body'] = $_POST['comment_body']; 
    header('location:'.$_SERVER['REQUEST_URI'].'');
    }
} 

第一个IF检查$_POST是否等于他们键入的最后一个值($_SESSION)。如果不相同,则运行下一个IF来测试$_POST变量是否为空。在最后一个朝向底部的IF内部,它将$_SESSION['dup_comment_body']设置为等于$_POST。因此,下次第一个IF运行时,如果$_POST相同,他们将收到消息"You have entered that"。希望这能有所帮助!

使用此代码

    if(isset($_POST)){
      header('location:'.$_SERVER['PHP_SELF']);
      die();
     }

为此需要使用POST/REDIRECT/GET模式。

Post/Rerect/Get(PRG)是一种web开发设计模式,可以防止一些重复的表单提交,为用户代理(用户)创建更直观的界面。PRG以可预测的方式支持书签和刷新按钮,不会创建重复的表单提交。

当web表单通过HTTP POST请求提交到服务器时,试图在某些用户代理中刷新服务器响应的web用户可能会导致重新提交原始POST请求的内容,从而可能导致不希望的结果,例如重复的web购买。

为了避免这个问题,许多web开发人员使用PRG模式——POST操作返回重定向命令,而不是直接返回网页。HTTP 1.1规范引入了HTTP 303("请参阅其他")响应代码,以确保在这种情况下,web用户的浏览器可以安全地刷新服务器响应,而不会导致重新提交初始POST请求。然而,目前使用的大多数常见商业应用程序(新的和旧的)在这些情况下仍然会继续发出HTTP302("已找到")响应。

以下是PHP中的一个示例:

header('Location: /yourpage.php', true, 303);
exit;

我的解决方案是,如果设置了后变量,则执行元刷新,刷新后$_post不跟随它。

<head>
<?php
  if (isset($_POST['Task'])){
  echo' <meta http-equiv="refresh" content="0; url=./ThisFile.php">';
  }
  ?>
</head>

如果您的表单要更新数据库,则只有在记录不存在的情况下才能更新或插入。只需先做一个select语句。这将防止由于刷新而导致的重复记录。

如果要将此表单的内容插入数据库,只需使用php/sql SELECT语句检查是否已提交"username"。如果是,则抛出一个错误。像这样:

//Database Values: servername, dbname, username and password;
//Also set ($_POST['username']) = $username or anything you like; 
$usererror = ""; //Will be filled later.
try { 
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt1 = $conn->prepare("SELECT * FROM yourdb WHERE username=:username");
$stmt1->bindParam(':email', $email);
$stmt1->execute();
$stmt1->fetch();
$querycheck = $stmt1->rowCount();
if ($querycheck >= 1) {
$usererror = "User already exists.";
}
}
catch(PDOException $e) {
// roll back the transaction if something failed
$conn->rollback();
echo "Critical Error. Contact admin immediately.";
error_log("Error: " . $e->getMessage(), 0); //logs connection errors instead of echoing the errors (for security reasons.)
}
$conn = null;

然后你现在只能插入没有错误的表格:

If (empty($usererror)) {
//insert command 
}

请注意,我使用了prepared语句,因为在许多文章中,它被认为是使用php+sql在数据库上操作最安全的方法。如果你没有真正的安全问题,你也可以使用普通的方法,它也会为你节省更多的代码行。

还要注意$querycheck>=1,确保1次插入并且永远不会超过1是非常重要的,即使用户刷新2000次,单击后退按钮并再次提交等。让我困扰并疯狂了几天的错误是使用$querycheck>1而不是$$querycheck>=1,我的表单在抛出"已经存在"错误之前一直提交了两次。最后,我已经解决了这个问题。希望这能帮助以后访问这个问题的人。

您可以在处理表单数据后重置$_POST数组,例如下面的代码

<?php
if( isset($_POST['submit']))
{
//do some processing related to form;
//after done.....
$_POST = array(); //this declares post as empty array 
//which is global variable anyways.
}
?>

或者第二种方法是使用隐藏的形式。。。。

<?php
if( isset($_POST['submit']))
{
//do some processing related to form;
//create a form with hidden field
?>
<form method="post" name="myform" action="actionpage">
<input type="hidden" name="somename" value="">
</form>
<?php
echo "<script> document.forms['myform'].submit();</script>";
}
?>

这基本上会提交带有1个空值字段的表单,我不知道这是否是最优的,但它满足了这里的需求。

相反,您可以使用诸如Recaptcha之类的captcha,它不允许在不进行captcha的情况下进行后期提交。这是我用过的,而且效果很好。