【问题标题】:Prevent duplicate data PHP Mysql防止重复数据 PHP Mysql
【发布时间】:2019-12-04 14:25:47
【问题描述】:

我有一个注册表单,但有一些问题。这是我的第一份登记表。数据收集需要的地方。

但是当有人注册时,PHPMyAdmin 中有很多重复的数据。我尝试了各种方法,但你知道,我只是一个学生。我想防止重复的电子邮件数据。

<?php
$link = mysqli_connect("localhost", "xxxx", "", "db");

// Check connection
if($link === false){
    die("ERROR: Could not connect. " . mysqli_connect_error());
}

// Escape user inputs for security
$nama = mysqli_real_escape_string($link, $_REQUEST['nama']);
$nohp = mysqli_real_escape_string($link, $_REQUEST['nohp']);
$email = mysqli_real_escape_string($link, $_REQUEST['email']);
$instagram = mysqli_real_escape_string($link, $_REQUEST['instagram']);

$sql = "INSERT INTO event (nama, nohp, email, instagram) VALUES ('$nama', '$nohp', '$email', '$instagram')";
if(mysqli_query($link, $sql)){
    echo "<p class='text-center'>Pendaftaran Berhasil. Akan kembali ke halaman utama dalam 5 detik.<br/>
    Atau klik <a href='index.php'>HOME</a></p>";
} else{
    echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
}

// close connection
mysqli_close($link);
?>

我需要在其中添加什么代码,以使已注册电子邮件的人无法再次注册?

对不起我的英语不好

【问题讨论】:

  • 使电子邮件列唯一
  • 你应该使用准备好的语句而不是转义输入。
  • @Tim OP 正在转义输入,因此除非有一些模糊的字符集配置,否则该值将变为 example@email.com\',\'\'); DELETE FROM event;--。最好使用准备好的语句,是的!但是转义在几乎所有情况下都有效(但它不是 100% 万无一失的,而且会导致代码混乱)。
  • 当您丢失数据库时,@Qirel 几乎所有还不够好。参数化查询(或准备好的语句)始终有效。

标签: php mysql


【解决方案1】:

你可以给 emailID 唯一的约束,当用户提交一个已经存在于表中的 emailID 的表单时,MYSQL 会抛出一个异常,你需要捕获并显示错误信息。 参考:https://www.w3schools.com/php/php_exception.asp

【讨论】:

    【解决方案2】:

    email 字段的唯一约束直接放在表列上。这将使您免于重复(由您的软件插入或以其他方式插入)。

    之后,如果电子邮件已经存在,您可以通过 PHP 脚本明确检查(但这会花费您额外的查询,因此不可行;此外,正如 Qirel 正确指出的那样,这将使您面临潜在的并发问题)或尝试插入并检查插入结果(正确且更安全的方式)。

    【讨论】:

    • 当您已经知道您有来自该异常的重复条目时,为什么还要执行额外的查询?
    • @KaiNeuwerth 我的意思是,在插入之前。我不鼓励这个解决方案,只是公开一个替代(最差)的解决方案。由于他是一名学生,我认为最好的办法是解释所有解决方案(甚至是坏的解决方案),警告他们并提出替代解决方案。
    • 如果您首先执行SELECT 查询以确定该值是否存在,您可能会遇到竞争条件。这极不可能发生,特别是对于较小的应用程序(因此,对于 99% 的情况,如果不是更多,它会做得很好),但它可能发生。最好在其上打一个唯一约束,在不检查的情况下插入它,如果约束失败则捕获错误。
    • 哦,我知道,我只是想多解释一下为什么这是个坏主意;-)
    • @Qirel 是的,我缺少这个信息。刚刚编辑了我的帖子;)
    【解决方案3】:

    您可以将UNIQUE 约束添加到电子邮件字段。这将通过运行以下查询来完成:

    ALTER TABLE `event` ADD UNIQUE (email);
    

    之后,当您想插入一个包含表中已存在电子邮件的新行时,您将收到如下错误:#1062 - Duplicate entry ...

    您可以像这样在 PHP 代码中捕获该异常并对其做出反应:

    <?php
    // perform INSERT query...
    if (mysqli_errno($link) == 1062) {
        print 'An error occured';
    }
    

    【讨论】:

    • 非常感谢。这解决了我的问题。非常感谢:)
    【解决方案4】:

    在您希望唯一的列上添加唯一约束,然后插入数据而不考虑重复 - 如果值重复,MySQL 将返回错误,因此您需要做的就是捕获错误。

    首先,将该表上的字段设为唯一值(这样做时,表上不能有重复值 - 如果event 表中有重复值,则必须先修复该问题)。

    ALTER TABLE event
    ADD UNIQUE (email);
    

    然后我们简单地尝试插入数据(使用准备好的语句而不是转义),并捕获错误 - 并检查属于唯一约束错误的错误代码。

    // Enable MySQLi exceptions 
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    
    try {
        // Connect to the database
        $link = new mysqli("localhost", "xxxx", "", "db");
    
        // Attempt to insert the data 
        $sql = "INSERT INTO event (nama, nohp, email, instagram) VALUES (?, ?, ?, ?)");
        $stmt = $link->prepare($sql);
        $stmt->bind_param("ssss", $_REQUEST['nama'], $_REQUEST['nohp'], $_REQUEST['email'], $_REQUEST['instagram']);
        $stmt->execute();
        $stmt->close();
    } catch (Exception $e) {
        if ($e->getCode() == 1062) { // 1062 = Unique constraint error code
            // Unique field error, handle it
            // If you only have unique on the email, example: 
            // echo 'The email already exists';
        } else {
            // Handle the error, something else went wrong
            error_log($e->getMessage());
            echo "An unexpected error occurred";
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-24
      • 2015-04-13
      • 2015-09-11
      相关资源
      最近更新 更多