HTML、Javascript、PHPで登録コードを書いています。以下のように(高いレベルで) 登録プロセスは次のとおりです。私の登録コードは、同じ電子メールを2回登録することを許可しています(フォームが複数回連続して非常に速く提出された場合のみ)
ユーザー:
1. HTMLフォームに自分の電子メール、名、およびパスワード(2回)を入力します。
2.「アカウントの作成」
3.ユーザのメールでメールが検索され、 が存在するかどうかが確認されます。
4.存在する場合は、既に登録されており、ログイン画面へのリンクが提供されていることが通知されます。 5.電子メールがまだ存在していない場合は、他のユーザーの詳細と一緒に私のデータベースのユーザーテーブルに挿入されます。
私のコードはこれを達成するためにはうまくいますが、 。ユーザーが「アカウントの作成」を複数回押すと、同じ電子メールアドレスが2回登録されます。これをやめるために何かできることはありますか?
ここに私のコードです:
はJQuery/Javascriptの
$("#registration_form").on("submit", function(e){
//this is called when the form is submitted i.e when "create account" is pressed
e.preventDefault();
var registration_email = $('#registration_email').val();
var registration_password = $('#registration_password').val();
var registration_password_confirmation = $('#confirm_registration_password').val();
var registration_display_name = $('#registration_display_name').val();
//validate fields and check if passwords match.
//all values have passed validation testing therefore make ajax request
var params = { 'registration_email' : registration_email, 'registration_password' : registration_password , 'registration_display_name' : registration_display_name, 'app_root_url':app_root_url};
$.ajax({
url: app_root_url + 'login_registration/registration_processing.php',
data: JSON.stringify(params),
type: "POST",
dataType: "json",
contentType: "application/json;charset=utf-8",
success: function(data){
var result = data;
var emailAlreadyExists = result.email_already_exists;
if(emailAlreadyExists){
//email already exists in our database and therefore the user is already registered so should use the login form
displayError('registration_feedback_message', 'This email already exists in the system. If you already have an account please <a href="#page-login">login here!</a>');
}else{
//email does not already exist in our database
}
}//end success
});//end ajax
});
registration_processing.php(このファイルの主要部分)
include_once '../includes/app_functions.php';
$app_root_url = filter_var($json->app_root_url, FILTER_SANITIZE_URL);
$email = filter_var($json->registration_email, FILTER_SANITIZE_EMAIL);
$password = filter_var($json->registration_password, FILTER_SANITIZE_STRING);
$display_name = filter_var($json->registration_display_name, FILTER_SANITIZE_STRING);
//more data filtering is performed here
$userPrivilegeID = 1; //basic user privilege
$userHasPassword = 1; //boolean 1 or 0
$profileImage = "images/profile_images/blank-avatar.png";
$results = registerUser($password, $email, $isAvatarImage, $profileImage, $userPrivilegeID, $display_name, $userHasPassword, $pdoConnection);
//create an array to store all values that we want to send back to the client side.
$data = array();
if($results['exception_occurred'] == true){
$data['exception_occurred'] = true;
$data['exception_message'] = $results['exception_message'];
echo json_encode($data);
}else{
$data['exception_occurred'] = false;
if($results['email_already_exists'] == true){
//email already exists. user is already registered and therefore has a password
//need to show error to user to say they are already registered and should use the login form.
$data['email_already_exists'] = true;
echo json_encode($data);
}else{
//email didnt exist so they have been registered
$data['email_already_exists'] = false;
//create an array which we will encrypt as our JWT token
$token = array();
$token['userID'] = $results['user_id'];
$token['email'] = $email;
$data['userID'] = $results['user_id'];
$data['user_is_subscriber'] = true;
$data['valid_user'] = true;
$data['userDetails'] = getProfile($results['user_id'], $pdoConnection);
$data['usertoken'] = JWT::encode($token, 'secret_server_key');
//echo data back to ajax request on client side
echo json_encode($data);
}
}
(app_functions.php中)のregisterUser機能
function registerUser($password, $email, $isAvatarImage, $profileImage, $userPrivilegeID, $display_name, $userHasPassword, $pdoConnection){
$data = array();
try{
$data['exception_occurred'] = false;
//first check if that email already exists just in case
$query = "SELECT COUNT(userID) FROM users WHERE emailAddress=:emailAddress";
$statement = $pdoConnection->prepare($query);
$statement->bindValue(':emailAddress', $email, PDO::PARAM_STR);
$statement->execute();
$rowCount = $statement->fetchColumn(0);
if($rowCount > 0){
//email already exists. user is already registered and therefore has a password
//need to show error to user to say they are already registered and should use the login form.
$data['email_already_exists'] = true;
return $data;
}else{
$data['email_already_exists'] = false;
$hashedPassword = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);
$query = "INSERT INTO users (emailAddress, password, isAvatarImage, profileImage, userPrivilegeID, displayName, userHasPassword) VALUES (:emailAddress, :password, :isAvatarImage, :profileImage, :userPrivilegeID, :displayName, :userHasPassword)";
$statement = $pdoConnection->prepare($query);
$statement->bindValue(':emailAddress', $email, PDO::PARAM_STR);
$statement->bindValue(':password', $hashedPassword, PDO::PARAM_STR);
$statement->bindValue(':isAvatarImage', $isAvatarImage, PDO::PARAM_INT);
$statement->bindValue(':profileImage', $profileImage, PDO::PARAM_STR);
$statement->bindValue(':userPrivilegeID', $userPrivilegeID, PDO::PARAM_INT);
$statement->bindValue(':displayName', $display_name, PDO::PARAM_STR);
$statement->bindValue(':userHasPassword', $userHasPassword, PDO::PARAM_INT);
$statement->execute();
$data['user_id'] = $pdoConnection->lastInsertId();
return $data;
}
}catch(PDOException $e){
//throw new pdoDbException($e);
$data['exception_occurred'] = true;
$data['exception_message'] = $e->getMessage();
return $data;
}
}
私が考えることができる1つの解決策は、複数のajaxリクエストを互いに近づけることができないように、「アカウントを作成」ボタンのタイマーを使用しますか?
編集
あなたのソリューションのいくつかを読んだ後、私は、電子メールフィールドはユニークな作りに探しています。ありがとう 私はphpMyAdminで作業していますので、「ユニーク」(画像で強調表示)を押すだけで簡単ですか?
編集2
私は一意のキーとして電子メールを作成しようと、私は次のエラーを取得:
編集]を3
エラーを解決するには上記(編集2で)メールアドレスフィールドの照合をutf8mb4_unicode_ciからutf8_unicode_cに変更しました私は再び "ユニーク"を押してみました。ありがとうございました
重複を避ける正しい方法は、アプリケーション内で競合するクエリではなく、データベース内でユニークな制約/インデックスを使用することです。 –
明らかにそうですが、それは簡単ですが、恐れている場合は、テーブルのコピーを作成し、それを他のテーブルで実行する前にテストしてください。 –