php 表单提交后取消设置帖子变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11765144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unset post variables after form submission
提问by roopunk
Is there a way to do the above? Basically, I don't want the form to be submitted again if someone presses refresh after already submitting the form once. In which case the browser asks, do you want to submit the form again. Will unset($_POST['username'])be of any help is this case?
有没有办法做到以上几点?基本上,如果有人在已经提交一次表单后按下刷新,我不希望再次提交表单。在这种情况下,浏览器会询问您是否要再次提交表单。会不会unset($_POST['username'])有任何帮助是这种情况?
采纳答案by raidenace
The post/redirect/get is a good option as some posters have already mentioned.
正如一些海报已经提到的那样,post/redirect/get 是一个不错的选择。
One another way I can think of is to set a session in the dostuff.php page to indicate that the posting has already been done. Check this session var each time to see if the page is being loaded again because of a page refresh.
我能想到的另一种方法是在 dostuff.php 页面中设置一个会话,以指示发布已经完成。每次检查此会话变量以查看页面是否因页面刷新而再次加载。
<?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..
}
?>
In the page you redirect to, unset the session var so that the form can be resubmitted again afresh, making it a new post operation. This will allow new form posts but will prevent post operations due to page refresh
在您重定向到的页面中,取消设置会话变量,以便可以重新重新提交表单,使其成为新的发布操作。这将允许新的表单发布,但会阻止由于页面刷新而导致的发布操作
回答by Pedro L.
Use an intermediate page to do the operations and then redirect.
使用中间页面进行操作,然后重定向。
For example:
例如:
mypage.php --> the page with the form
mypage.php --> 带有表单的页面
dostuff.php --> receives the form data and makes operations, then redirects to any other page.
dostuff.php --> 接收表单数据并进行操作,然后重定向到任何其他页面。
To do a redirect:
Put this line on the top of "dostuff.php": header("Location: mypage.php");
要进行重定向:
将此行放在“dostuff.php”的顶部:header("Location: mypage.php");
回答by Vijay Sankar
Use this code
使用此代码
if(isset($_POST)){
header('location:'.$_SERVER['PHP_SELF']);
die();
}
回答by Explosion Pills
The problem you are facing above specifically can (and should) be solved with Post/Redirect/Get. Unsetting _POSTon the php side would be ineffective since the problem is it is a separate request.
您在上面特别面临的问题可以(并且应该)通过Post/Redirect/Get解决。解封_POST,因为问题是它是一个单独的请求在PHP端将是无效的。
You also have to deal with double-clicking of submission buttons. You can solve this on the client side by disabling form submission after the button click, or by putting a random token in the form and storing that token in the session. The token will be accepted only once (session keeps track of whether the token has been posted).
您还必须处理双击提交按钮的问题。您可以在客户端通过在单击按钮后禁用表单提交来解决此问题,或者在表单中放置一个随机令牌并将该令牌存储在会话中。令牌只会被接受一次(会话会跟踪令牌是否已发布)。
回答by Explosion Pills
Here's a nice method I use to keep users from submiting the same data twice, which will also prevent the page from adding the same record to the database when reload.
这是我用来防止用户两次提交相同数据的好方法,这也将防止页面在重新加载时向数据库添加相同的记录。
// 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'].'');
}
}
The first IFchecks to see if the $_POSTis equal to the last thing they typed ($_SESSION). If it's not the same it runs the next IFto test if the $_POSTvariable is not empty. Inside the last IFtowards the bottom it sets $_SESSION['dup_comment_body']to equal the $_POST. So next time the first IFruns and the $_POSTis the same, they will get the message "You already entered that.". Hope this helps!
第一个IF检查$_POST是否等于他们输入的最后一个内容 ( $_SESSION)。如果不相同,则运行下一个IF以测试$_POST变量是否为空。在IF朝向底部的最后一个内部,它设置$_SESSION['dup_comment_body']为等于$_POST. 因此,下次第一次IF运行并且相$_POST同时,他们将收到消息“您已经输入了那个。”。希望这可以帮助!
回答by John Conde
You need to use the POST/REDIRECT/GET patternfor this.
为此,您需要使用POST/REDIRECT/GET 模式。
Post/Redirect/Get (PRG) is a web development design pattern that prevents some duplicate form submissions, creating a more intuitive interface for user agents (users). PRG supports bookmarks and the refresh button in a predictable way that does not create duplicate form submissions.
When a web form is submitted to a server through an HTTP POST request, a web user that attempts to refresh the server response in certain user agents can cause the contents of the original POST request to be resubmitted, possibly causing undesired results, such as a duplicate web purchase.
To avoid this problem, many web developers use the PRG pattern—instead of returning a web page directly, the POST operation returns a redirection command. The HTTP 1.1 specification introduced the HTTP 303 ("See other") response code to ensure that in this situation, the web user's browser can safely refresh the server response without causing the initial POST request to be resubmitted. However most common commercial applications in use today (new and old alike) still continue to issue HTTP 302 ("Found") responses in these situations.
Post/Redirect/Get (PRG) 是一种 Web 开发设计模式,可以防止一些重复的表单提交,为用户代理(用户)创建更直观的界面。PRG 以一种可预测的方式支持书签和刷新按钮,不会创建重复的表单提交。
当通过 HTTP POST 请求将 Web 表单提交到服务器时,尝试在某些用户代理中刷新服务器响应的 Web 用户可能会导致重新提交原始 POST 请求的内容,从而可能导致不希望的结果,例如重复网上购买。
为了避免这个问题,很多 web 开发者使用 PRG 模式——POST 操作返回一个重定向命令而不是直接返回一个网页。HTTP 1.1 规范引入了 HTTP 303(“查看其他”)响应代码,以确保在这种情况下,Web 用户的浏览器可以安全地刷新服务器响应,而不会导致重新提交初始 POST 请求。然而,在这些情况下,当今使用的大多数常见商业应用程序(新的和旧的)仍然继续发出 HTTP 302(“找到”)响应。
Here's an example in PHP:
这是 PHP 中的一个示例:
header('Location: /yourpage.php', true, 303);
exit;
回答by Robert
If your form is going to be updating a database, then you can update or insert only if record does not exist. Simply do a select statement first. This will prevent duplicate records due to refresh.
如果您的表单要更新数据库,则只有在记录不存在时才可以更新或插入。只需先做一个选择语句。这将防止由于刷新而导致重复记录。
回答by Chimdi
If you are inserting the contents of this form to database, simply use the php/sql SELECT statement to check if "username" has already been submitted. If yes, throw an error. Like so:
如果您将此表单的内容插入数据库,只需使用 php/sql SELECT 语句检查“用户名”是否已提交。如果是,则抛出错误。像这样:
//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;
Then you can now insert only the form has no error:
然后你现在可以只插入没有错误的表单:
If (empty($usererror)) {
//insert command
}
Notice I used prepared statements, because on many articles, it is said to be the safest method to operate on Databases using php+sql. You can as well use the normal method if you don't really have security concerns, it'll save you more code lines too.
注意我使用了prepared statement,因为在很多文章中都说使用php+sql操作数据库是最安全的方法。如果你真的没有安全问题,你也可以使用普通方法,它也会为你节省更多的代码行。
Also notice the $querycheck >= 1, it is very essential to ensure 1 insertion and never more than 1 even if the user refreshes 2,000 times, clicks back button and submit again etc. The mistake that tied me down and drove me mad for days was using $querycheck > 1instead of $querycheck >= 1, that way, my forms kept submitting twice before throwing "Already Exists" error. Finally, I've been able to fix it. Hope this helps people that will visit this question later.
还要注意$querycheck >= 1,即使用户刷新 2,000 次,单击后退按钮并再次提交等,确保 1 次插入并且永远不会超过 1 次插入非常重要。这个错误让我感到沮丧并让我发疯了好几天正在使用$querycheck > 1而不是$querycheck >= 1,这样,我的表单在抛出“Already Exists”错误之前一直提交两次。最后,我已经能够修复它。希望这可以帮助稍后访问此问题的人。
回答by Michael E
My solution for this is doing a meta refresh if a post variable is set the $_POST do not follow it after the refresh.
如果设置了 post 变量,我的解决方案是进行元刷新,刷新后 $_POST 不跟随它。
<head>
<?php
if (isset($_POST['Task'])){
echo' <meta http-equiv="refresh" content="0; url=./ThisFile.php">';
}
?>
</head>
回答by The Gamer King
Instead, you could use a captcha such as Recaptcha that doesn't allow post submission without doing the captcha. This is what I used and it works perfectly.
相反,您可以使用诸如 Recaptcha 之类的验证码,它不允许在不进行验证码的情况下提交帖子。这是我使用的,它完美地工作。

