2012-12-05 118 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变量存储最后一个散列的时间,所以你可以在一两秒后过期。