可以使用PHP“;如果;关于SELECT查询结果的语句,以确定执行INSERT查询是否会导致意外的数据重叠?
我是一名学生,这是我第一次写一个软件。它是LAMP堆栈上的web应用程序,作为该web应用程序的一部分,我编写了以下函数,用于在创建新用户时与数据库交互:可以使用PHP“;如果;关于SELECT查询结果的语句,以确定执行INSERT查询是否会导致意外的数据重叠?,php,mysql,sql,database,Php,Mysql,Sql,Database,我是一名学生,这是我第一次写一个软件。它是LAMP堆栈上的web应用程序,作为该web应用程序的一部分,我编写了以下函数,用于在创建新用户时与数据库交互: public function CreateUser($username, $password, $email){ global $DBHandler, $SQLStatement; $SQLStatement = $DBHandler->prepare("SELECT id FROM users WHERE username
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数据对象在别处启动
它遵循以下基本步骤:
是否可以将此脚本中的3个查询合并为1个查询,并使用SQL而不是PHP表示的相同if/else逻辑,如果可以,是否可以提高性能和/或防止出现上述情况?对于更并行的解决方案,可以将
插入设置为有条件的:
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%安全的,但在实践中应该足够了
请注意,用户创建中的并发问题是一个奢侈的问题。我只是建立了一个基本的版本,就像你拥有的一样,并专注于你网站更有趣的方面 这里要做的是编写一个非常原始的对象关系管理器(ORM)。是否使用帮助或这是一个学术练习?您也不应该使用全局SQL语句对象。总是创建一个新的函数作为函数的一部分。我认为将盐存储在数据库中会泄露它?我会说这个项目是学术性的,但不是练习。成绩的一部分是创建一个我们个人想要创建的网站,满足我们课外生活的一些需要。其他大多数学生都在写博客、相册之类的东西,但我正在写一个类似于论坛的交流平台。我做了大量关于盐分和散列的研究,因为安全让我着迷,我得到的总体印象是盐分不是秘密的,它们对于每个用户来说都是独一无二的。所以有人可以得到所有的salt和hash,但是因为每个salt都是唯一的,所以他们不能使用彩虹表,他们仍然必须单独对每个帐户进行暴力攻击。所以说得清楚一点,我描述的场景可能真的会发生吗?我知道这不太可能,但这种可能性是否意味着我的代码肯定是错误的做法?如果我继续这样做,像这样的并发可以做各种各样的讨厌的事情,不是吗?是的,这可能会发生,而且在很多网站上都会发生。这其实并不重要,因为很少有网站有大量的注册,用户总是可以使用不同的名称重试。而不是编写用户管理代码,试图解释许多罕见的情况下,你可以考虑使用OpenID,像StAcExopp.0。