gpt4 book ai didi

php - 是否可以使用 PHP "if"语句对 SELECT 查询的结果来确定是否执行 INSERT 查询会导致意外的数据重叠?

转载 作者:可可西里 更新时间:2023-11-01 07:08:21 24 4
gpt4 key购买 nike

我是一名学生,这是我第一次编写软件。它是 LAMP 堆栈上的 Web 应用程序,作为该 Web 应用程序的一部分,我编写了以下函数以在创建新用户时与数据库交互:

public function CreateUser($username, $password, $email){
global $DBHandler, $SQLStatement;
$SQLStatement = $DBHandler->prepare("SELECT id FROM users WHERE username = :username AND verified > 0");
$SQLStatement->bindParam(':username', $username);
$SQLStatement->execute();
$check = $SQLStatement->fetch();
if ($check['id']){
return 2;
}else{
$SQLStatement = $DBHandler->prepare("SELECT id FROM users WHERE email = :email AND verified > 0");
$SQLStatement->bindParam(':email', $email);
$SQLStatement->execute();
$check = $SQLStatement->fetch();
if ($check['id']){
return 3;
}else{
/* Edited out code that generates a random verification code, a random salt, and hashes the password. */
$SQLStatement = $DBHandler->prepare("INSERT INTO users (username, email, passwordhash, salt, verifycode) VALUES (:username, :email, :passwordhash, :salt, :verifycode)");
$SQLStatement->bindParam(':username', $username);
$SQLStatement->bindParam(':email', $email);
$SQLStatement->bindParam(':passwordhash', $passwordhash);
$SQLStatement->bindParam(':salt', $salt);
$SQLStatement->bindParam(':verifycode', $verifycode);
$SQLStatement->execute();
return 1;
}
}
}

$DBHandler 在别处作为 PHP 数据对象启动。

它遵循以下基本步骤:

  1. 查询数据库以查看是否有人已经使用所需用户名验证了帐户。
  2. 如果用户名可用,请执行另一个查询并对电子邮件执行相同的检查。
  3. 如果用户名和电子邮件都可用,则生成验证码、salt、散列密码,进行第三次查询以将所有内容写入数据库,然后返回 1(表示成功)。

想法是在您的帐户通过验证(已验证 =“1”)之前不会保留用户名和电子邮件。在其他地方,如果您单击通过电子邮件发送的验证链接,则有一个脚本会将您的已验证列更改为“1”。

我的第一个问题是:

A 提议使用用户名“Lorem”,B 有一个未验证的帐户也提议使用用户名“Lorem”。是否可以按以下顺序执行查询?

  1. A 的脚本确定用户名“Lorem”未被经过验证的用户使用
  2. B 的脚本使用用户名“Lorem”验证他们的帐户
  3. A 的脚本创建了用户名为“Lorem”的未经验证的帐户

我的第二个问题是:

是否可以将此脚本中的 3 个查询合并为 1 个查询,并使用 SQL 而不是 PHP 表达相同的 if/else 逻辑,如果是这样,是否会提高性能和/或防止上述情况发生?

最佳答案

对于更并发的解决方案,您可以使 insert 有条件:

insert  into users 
(username, email, ...)
select :username, :email, ...
where not exists
(
select *
from users
where verified > 0
and (username = :username
or email = :email)
)

这在 MySQL 中仍然不是 100% 安全的,但在实践中应该足够了。

注意,创建用户的并发问题是一个奢侈问题。我只是设置了一个像您所拥有的那样的基本版本,并专注于您网站更有趣的方面!

关于php - 是否可以使用 PHP "if"语句对 SELECT 查询的结果来确定是否执行 INSERT 查询会导致意外的数据重叠?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12445014/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com