2012-12-05 159 views
2

我這個代碼測試:PHP的MySQL防止快速的形式重複插入提交

<?php 
$db = new PDO('mysql:host=localhost;dbname=test', 'root', 'root'); 

if(filter_has_var(INPUT_POST, 'submit')) { 

    $r = $db->query('SELECT * FROM test WHERE value="'.$_POST['value'].'"'); 
    $n = $r->rowCount(); 

    for ($i=0; $i<=10000000; $i++) { 
    // do nothing 
    } 

    if (!$n) { 
    $db->query('INSERT INTO test (id, value) VALUES (NULL, "'.$_POST['value'].'")'); 
    } 

} 
?> 

<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"> 
    <input type="text" name="value" value=""> 
    <input type="submit" name="submit" value="Submit"> 
</form> 

當測試Safari中的上述表格我能提交相同的值到我的數據庫多次通過快速點擊提交按鈕。

但是,當我使用此代碼測試:

<?php 
$db = new PDO('mysql:host=localhost;dbname=test', 'root', 'root'); 

if(filter_has_var(INPUT_POST, 'submit')) { 

    for ($i=0; $i<=10000000; $i++) { 
    // do nothing 
    } 

    $r = $db->query('SELECT * FROM test WHERE value="'.$_POST['value'].'"'); 
    $n = $r->rowCount(); 

    if (!$n) { 
    $db->query('INSERT INTO test (id, value) VALUES (NULL, "'.$_POST['value'].'")'); 
    } 

} 
?> 

有條件的作品,我無法同值多次提交不管我怎麼快速點擊提交按鈕。

有沒有可靠的方法來防止重複的數據庫插入與第一個代碼片段發生,以便它的行爲就像第二個片段?

+0

如果您不希望表中的多行具有相同的值,則應在數據庫中使用唯一約束對其進行設置。 –

回答

2

通常,客戶端處理程序可幫助停止意外快速提交,但我通常選擇使用_SESSION變量的服務器端解決方案。只要創建了$_POST陣列的哈希值,將其存儲爲一個會話變量,然後比較提交_POST給湊版本下一:

session_start(); 
//if this is the first time they've posted, just create a placeholder session var 
if (!isset($_SESSION['repost_hash'])){$_SESSION['repost_hash']="";} 

//if the post array is a duplicate, nullify the submission 
if (isset($_POST) && md5(serialize($_POST)) == $_SESSION['repost_hash']){ 
    unset($_POST); 
} else { //otherwise, if this is new data, update the stored hash 
    $_SESSION['repost_hash'] = md5(serialize($_POST)); 
} 
... 

如果您只想停止重複,提交了很短的時間週期,你還可以有第二個$_SESSION變量存儲最後一個散列的時間,所以你可以在一兩秒後過期。