2014-04-06 208 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