在PHP中提交表单时如何防止多个插入?

有时用户可能会按两次Enter ,并且插入两次。

有没有一个解决scheme来防止这个,而不是检查是否已经有一个相同的titlecontent的职位?

有几个解决这个问题的方法:

  1. 发布时使用Javascript来禁用表单的提交button。 这是绝对不是一个万无一失的方法。 提交表单实际上没有点击button是非常容易的,而且对禁用JavaScript的用户也不适用。 我绝对不会推荐这种方法。

    例:

     <script language="javascript"> <!-- function disableSubmitButton() { // you may fill in the blanks :) } --> </script> <form action="foo.php" method="post"> <input type="text" name="bar" /> <input type="submit" value="Save" onclick="disableSubmitButton();"> </form> 
  2. 使用PHP会话将post会话variables(例如$ _SESSION ['posttimer'])设置为当前时间戳。 在PHP中实际处理表单之前,检查$ _SESSION ['posttimer']variables是否存在,并检查某个时间戳差异(IE:2秒)。 这样,你可以很容易地过滤掉双重提交。

    例:

     // form.html <form action="foo.php" method="post"> <input type="text" name="bar" /> <input type="submit" value="Save"> </form> // foo.php if (isset($_POST) && !empty($_POST)) { if (isset($_SESSION['posttimer'])) { if ( (time() - $_SESSION['posttimer']) <= 2) { // less then 2 seconds since last post } else { // more than 2 seconds since last post } } $_SESSION['posttimer'] = time(); } 
  3. 在每个POST中包含一个唯一的标记。 在这种情况下,您还可以将会话variables设置为要包含的令牌,然后在窗体中呈现该令牌。 表单提交后,您将重新生成令牌。 当提交的标记与会话中的标记不匹配时,表单已被重新提交并应被宣布为无效。

    例:

     // form.php <?php // obviously this can be anything you want, as long as it is unique $_SESSION['token'] = md5(session_id() . time()); ?> <form action="foo.php" method="post"> <input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?>" /> <input type="text" name="bar" /> <input type="submit" value="Save" /> </form> // foo.php if (isset($_SESSION['token'])) { if (isset($_POST['token'])) { if ($_POST['token'] != $_SESSION['token']) { // double submit } } } 

在post中使用唯一标记,以便每个post/回发只处理一次。

禁用提交button不是一个很好的解决scheme,因为人们可以closuresJavaScript,或做其他奇怪的事情。 客户端validation是一个好的开始,但也应该始终使用服务器端处理来进行备份。

生成一个唯一的一次性使用密钥,用表单提交。

依靠Javascript是一个坏主意,因为它可能已被用户禁用在客户端。 使用密钥scheme,当服务器接收到提交时,可以locking该密钥的提交。 无论你喜欢,你都可以对重复的提交做出回应。

对于这种方法的工作,键必须是独特的,非常难以预测。 否则,某些表单可能会因关键冲突而被locking。 所以你不必跟踪每个表单提交的密钥,避免冲突,密钥应该过期与该用户的会话。 另外要注意的是,如果恶意用户能够预测密钥,那么您的代码可能容易受到某种劫持或DOS攻击。

防止重复的表单提交显示了一个没有JavaScript的做法。

提交表单( onsubmit )后,使用Javascript禁用提交button。

请注意,如果用户禁用Javascript,他们仍然可以提交两次。 无论这种情况是否经常发生,足以certificate你的代码(如你在你的问题中提到的那样)是由你自己决定的。

或者,使用一次性表单键。

我使用这个:

 $form_token = $_SESSION['form_token'] = md5(uniqid()); 

发送$ form_token的forms,然后…

我检查了form_token:

 if($_SESSION['form_token'] != $_POST['form_token']) { echo 'Error'; } 

一旦用户提交表单,使用JavaScript禁用提交button。 这就是,例如,当你回答一个问题时,StackOverflow使用。

例如

 <input type="submit" onclick="this.disabled=true" /> 

按两次提交很less会导致多个插入,但如果你想要一个简单的溶剂,使用

 onsubmit="document.getElementById('submit').disabled = true" 

在表单标签中,只要你提交你的提交buttonid="submit"

一旦点击button,就可以使用JavaScript来禁用button。

 onclick="this.disabled=true;forms[0].submit();" 

另一种创build确认页面的方法,用户可以最终按下提交button。 这可能会减less这种可能性。

Aron Rotteveel's 在每个POST上都包含一个独特的令牌 。 但是,我的表单仍然会在用户刷新页面时提交(F5)。 我设法通过添加重置来解决这个问题:

  // reset session token $_SESSION['token'] = md5( $_POST['token'] . time() ); 

我的最终脚本是这样的:

 if (isset($_SESSION['token'])) { if (isset($_POST['token'])) { if ($_POST['token'] != $_SESSION['token']) { echo '<h3>Oops! You already submitted this request.</h3>'; } else { // process form // reset session token $_SESSION['token'] = md5( $_POST['token'] . time() ); } } else { echo 'post token not set'; $_SESSION['token'] = md5( $somevariable . time() ); } } 

哦! 不要忘记添加session_start();<!DOCTYPE>之前

我是一个PHP新手,所以请纠正我,如果你发现违规行为。

使用JavaScript来阻止它发送