2014-04-06 211 views
1

我试过the method suggested on this site以防止重复表单提交,但在提交表单后(表单通过验证),我总是收到错误Invalid secret key!。问题是什么?防止重复表单提交

PHP:

<?php 
     . 
     . 
     . 
     session_start(); 
     $secret = md5(uniqid(rand(), true)); 
     $_SESSION['FORM_SECRET'] = $secret; 

     // Send Message 
     if (isset($_POST['send'])) 
     { 
      $name = strip_tags(trim($_POST['name'])); 
      $email = strip_tags(trim($_POST['email'])); 
      $subject = strip_tags(trim($_POST['subject'])); 
      $message = strip_tags(trim($_POST['message'])); 

      $valid_name = $name=='' || (mb_strlen($name) > 2 && preg_match('/^\p{L}+$/u', $name)); 
      $valid_email = filter_var($email, FILTER_VALIDATE_EMAIL); 
      $valid_subject = $subject!=''; 
      $valid_message = $message!=''; 

     if ($valid_name && $valid_email && $valid_subject && $valid_message) { 

      $form_secret = isset($_POST['form_secret'])?$_POST['form_secret']:''; 

      if(isset($_SESSION['FORM_SECRET'])) { 
      if(strcasecmp($form_secret, $_SESSION['FORM_SECRET']) == 0) { 

       sendEmail($name, $email, $name, $email, $subject, $message, $support_email); 
       $PAGE_MESSAGE = "Message has been sent!";   
       unset($_SESSION['FORM_SECRET']); 

      } else { 
       //Invalid secret key 
       $PAGE_ERROR = "Invalid secret key!"; 
      } 
      } else { 
      //Secret key missing 
      $PAGE_ERROR = "Form data has already been processed!"; 
      } 

     } else { 
      $PAGE_ERROR = "Error (not valid)!"; 
     } 
     }     
    }  
    ?> 

HTML:

<form enctype="multipart/form-data" method="POST"> 
    <input type="hidden" name="form_secret" id="form_secret" value="<?php echo $_SESSION['FORM_SECRET'];?>" /> 
    . 
    . 
    . 
    <input type="submit" name="send" value="Send" /> 
+0

你是否在HTML表单存在的页面开始会话? – CMPS

+0

当然可以! – user2406937

+0

尝试像这样调试它:echo $ form_secret。“==”。$ _ SESSION ['FORM_SECRET']; – CMPS

回答

3

example you link to笔者建议这样做:

if(isset($_SESSION["FORM_SECRET"])) { 
    if(strcasecmp($form_secret, $_SESSION["FORM_SECRET"]) === 0) { 

但在你的榜样,你这样做是:

if(isset($_SESSION['FORM_SECRET'])) { 
    if(strcasecmp($form_secret, $_SESSION['FORM_SECRET']) == 0) { 

请注意,在原始中,正在使用===比较运算符,但在您的使用中,您正在使用==

此外,在您的形式,确实为form_secret值永远真正得到执行此操作时设置:

<input type="hidden" name="form_secret" id="form_secret" value="<?php echo $_SESSION['FORM_SECRET'];?>" /> 

在我看来,如果不知道你的HTML表单& PHP的更大的结构,这是硬进行调试。但我有一个想法,基于事实我们的PHP有这样的事实:

session_start(); 
$secret = md5(uniqid(rand(), true)); 
$_SESSION['FORM_SECRET'] = $secret; 

但是,窗体然后处理下面。所有将要执行的操作都将重置$_SESSION['FORM_SECRET']的值。相反,代码块需要在HTML表单页面中。也许是这样的:

<?php 
session_start(); 
$secret = md5(uniqid(rand(), true)); 
$_SESSION['FORM_SECRET'] = $secret; 
?> 
<form enctype="multipart/form-data" method="POST"> 
<input type="hidden" name="form_secret" id="form_secret" value="<?php echo $_SESSION['FORM_SECRET'];?>" /> 
. 
. 
. 
<input type="submit" name="send" value="Send" /> 

然后在你的PHP处理表单这应该是唯一的会话相关的线路:

<?php 
    . 
    . 
    . 
    session_start(); 

    // Send Message 
    if (isset($_POST['send'])) 
    { 

的整体思路是,<input type="hidden" name="form_secret"…设置与$secret = md5(uniqid(rand(), true));值当传递到$_SESSION['FORM_SECRET']。然后session_start();允许你的PHP拿起$_SESSION['FORM_SECRET'] &的值对它进行操作。

的想法是,形式有一个隐藏的form_secret值&的$_SESSION['FORM_SECRET']也有类似的秘密设置。而HTML表单为表单页面的每次加载都创建了一个新值,这使得您可以在表单中嵌入的内容隐藏在会话本身的值之间进行比较。

+0

与===相同的问题。 – user2406937

+1

查看我的编辑。我认为你需要更好地理解'$ _SESSION'值的整体概念。 – JakeGould