私は学生で、ソフトウェアを書くのはこれが初めてです。これは 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 データ オブジェクトとして別の場所で開始されます。
次の基本的な手順に従います。
- データベースにクエリを実行して、誰かが目的のユーザー名を持つアカウントを既に確認しているかどうかを確認します。
- ユーザー名が使用可能な場合は、別のクエリを実行し、電子メールに対して同じチェックを実行します。
- ユーザー名と電子メールの両方が利用可能な場合、検証コードを生成し、ソルトし、パスワードをハッシュし、3 番目のクエリを実行してすべてをデータベースに書き込み、1 (成功を意味します) を返します。
アカウントが確認されるまで (確認済み = '1')、ユーザー名と電子メールは予約されません。他の場所には、電子メールで送信された確認リンクをクリックすると、確認済みの列を「1」に変更するスクリプトがあります。
私の最初の質問はこれです:
人物 A はユーザー名 "Lorem" を提案しており、人物 B もユーザー名 "Lorem" を提案している未確認のアカウントを持っています。次の順序でクエリを実行することは可能ですか?
- ユーザー A のスクリプトは、ユーザー名 "Lorem" が確認済みのユーザーによって使用されていないと判断します
- ユーザー B のスクリプトは、ユーザー名「Lorem」で自分のアカウントを検証します
- ユーザー A のスクリプトは、ユーザー名「Lorem」で未確認のアカウントを作成します
私の2番目の質問は次のとおりです。
このスクリプトの 3 つのクエリを、PHP ではなく SQL で表現された同じ if/else ロジックを使用して 1 つのクエリに結合することは可能ですか? その場合、パフォーマンスが向上し、上記のシナリオが発生するのを防ぐことができますか?