英文:
Checking DB for existing record with PHP PDO
问题
我正在尝试检查数据库是否有记录,以防止重复。我正在使用以下代码:
$stmt = $db->prepare('SELECT * FROM newsletter WHERE useremail=:useremail');
$stmt->bindParam(':useremail', $_GET['useremail'], PDO::PARAM_INT);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row) {
echo "";
} else {
$kaydet = $db->prepare("INSERT INTO newsletter SET useremail=:useremail");
$insert = $kaydet->execute(array('useremail' => $_POST['useremail']));
if ($insert) {
header("Location:../index.php?status=success");
exit;
} else {
header("Location:../index.php?status=error");
exit;
}
}
<details>
<summary>英文:</summary>
I am trying to check if the database has the record to prevent duplicates. I am using the following code:
$stmt = $db->prepare('SELECT * FROM newsletter WHERE useremail=:useremail');
$stmt->bindParam(':useremail', $_GET['useremail'], PDO::PARAM_INT);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row) {
echo "<script type='text/javascript'>Swal.fire('Info', 'This email is already registered.','info')";
} else {
$kaydet = $db->prepare("INSERT INTO newsletter SET useremail=:useremail");
$insert = $kaydet->execute(array('useremail' => $_POST['useremail']));
if ($insert) {
header("Location:../index.php?status=success");
exit;
} else {
header("Location:../index.php?status=error");
exit;
}
}
I aim to prevent form submission for duplicate records. But this is not working. Any help would be appreciated.
Thank you.
</details>
# 答案1
**得分**: 0
在PHP中执行`SELECT`、检查结果、执行`INSERT`的问题在于它容易受到竞态条件的影响。一个线程可能正要执行`insert`,而另一个线程正在执行`select`,此时未返回任何行并且即将执行`insert`,这样就会产生重复数据。
面对这种情况,让数据库来处理。
为表上的`useremail`(或主键)添加一个唯一索引可以解决这个问题。
尝试执行插入操作,如果出现重复键异常,那就触发`'This email is already registered.'`,否则就是成功添加。
<details>
<summary>英文:</summary>
The problem with doing `SELECT`, check result, do `INSERT`, in PHP is that it is subject to race conditions. One thread could be about to do the `insert` just as the other `select`s no rows and about to also do an `insert`, and now you have duplicates.
When confronted with this situation, let the database handle it.
A unique index on `useremail` (or primary key), for the table will resolve this.
Attempt the insert, if you get a duplicate key exception, then that's when you fire `'This email is already registered.'`, otherwise its a successful addition.
</details>
# 答案2
**得分**: -1
我认为问题出在
```php
$stmt->bindParam(':useremail', $colour, PDO::PARAM_STR);
使用上述代码而不是param int
https://www.php.net/manual/en/pdostatement.bindparam.php
英文:
i think the problem is with the
$stmt->bindParam(':useremail', $colour, PDO::PARAM_STR);
Use above instead of param int
https://www.php.net/manual/en/pdostatement.bindparam.php
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论