電子メールでアクティベーション コードを送信する登録システムを開発しました。そのユーザー名が既に存在する場合は、「ユーザー名が既に存在します」というエラーが返されます。
データベースにユーザーがいない場合、登録した最初のユーザー名は「ユーザー名は既に存在します!」を返します。ユーザーをデータベースに自動的に挿入します。
しかし、もう一度試してみると、すでにデータベースにユーザーがいる場合、完全に機能します。
そこに何が問題なのですか?
登録方法:
/**
* Public Method Register
*
* Registers the user to the system, checking for errors.
* If error was found, it will throw new exception.
*
* @parm username The username the user posted.
* @parm password The password the user posted.
* @parm repassword The validated password the user posted.
* @parm email The email the user posted.
* @parm reemail The validated email the user posted.
* @parm day The day the user posted (for date of birth).
* @parm month The month the user posted (for date of birth).
* @parm year The year the user posted (for date of birth).
*
* @return Return true means everything is correct, register successfully.
**/
public function register($username, $password, $repassword, $email, $reemail, $day, $month, $year)
{
// Check if passwords matching.
if ($password != $repassword)
{
throw new exception ("Passwords does not match.");
}
// Check if emails matching.
else if ($email != $reemail)
{
throw new exception ("Emails does not match.");
}
//Query to check if username is taken.
$this->user = $this->pdo->prepare("SELECT * FROM users WHERE user_name = :name");
$this->user->execute(array(":name" => $username));
//Query to check if email is taken.
$this->email = $this->pdo->prepare("SELECT * FROM users WHERE user_email = :email");
$this->email->execute(array(":email" => $email));
// Checking if username is taken using the query.
if ($this->user->rowCount())
{
throw new exception ("That username is already in use!");
}
// Checking if email is taken using the query.
else if ($this->email->rowCount())
{
throw new exception ("Email is already in use");
}
// Checking if birth of date is valid.
else if ($day > 31 || $month > 12 || $year > date('Y') || $year < 1925)
{
throw new exception ("Invalid Birth of date");
}
//checking if password is more than 5 characters long.
else if (strlen($password) < 5)
{
throw new exception ("Password is too short");
}
else
{
// The main insert query
$this->insert = $this->pdo->prepare
("
INSERT INTO users
(user_name, user_password, user_email, user_birth)
VALUES
(:username, :password, :email, :birth)
");
// Everything is fine, insert data.
$this->insert->execute(array
(
":username" => $username,
":password" => $password,
":email" => $email,
":birth" => $day.'/'.$month.'/'.$year
));
//Send verification
$this->sendVerification($username, $email);
//Finished processing, return true.
return true;
}
}
データベースの構築:
Field Type Collation Attributes Null Default Extra Action
user_name varchar(100) latin1_swedish_ci No None
user_password varchar(255) latin1_swedish_ci No None
user_email varchar(255) latin1_swedish_ci No None
user_id int(100) No None AUTO_INCREMENT
is_admin int(1) No None
is_mod int(1) No None
user_avatar varchar(255) latin1_swedish_ci No None
user_ip varchar(100) latin1_swedish_ci No None
user_birth varchar(100) latin1_swedish_ci No None
user_registration_date varchar(100) latin1_swedish_ci No None
user_theme_downloads int(100) No None
user_theme_pruchases int(100) No None
is_verified int(1) No 0
lastLogin timestamp on update CURRENT_TIMESTAMP No CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
登録コール:
try
{
$users->register($_POST['name'], $_POST['pass'], $_POST['pass2'], $_POST['email'], $_POST['email2'], $_POST['day'], $_POST['month'], $_POST['year']);
$_SESSION['registered'] = $_POST['email'];
}
catch (exception $e)
{
$error = '<div class="alert-danger">'.$e->getMessage().'</div>';
}
詳しくは:
メールの送信が次のエラーで失敗します。
13.05.17 01:28:03 : Must issue a STARTTLS command first. g7sm13929808eew.15 - gsmtp<EOL>
13.05.17 01:32:28 : Must issue a STARTTLS command first. g7sm13954936eew.15 - gsmtp<EOL>
13.05.17 01:56:20 : Must issue a STARTTLS command first. c42sm14092691eeb.10 - gsmtp<EOL>
13.05.17 16:33:46 : Socket Error # 11004<EOL>
13.05.17 21:44:19 : Must issue a STARTTLS command first. y10sm20698432eev.3 - gsmtp<EOL>
Gmail アカウントを使用すると、2 週間前までは機能していました。
検証方法:
/**
* Private Method sendVerification
*
* Sends the account a verification ID to his email
* Generates verification ID string using SHA512
* using the static method for our random string
* generation.
*
* @parm username The username public function register
* requested.
* @parm email The email public function register requested
**/
private function sendVerification($username, $email)
{
$salt = self::generateSalt($email, $username);
$this->check = $this->pdo->prepare("SELECT * FROM users where user_name = :username AND user_email = :email");
$this->check->execute(array
(
":username" => $username,
":email" => $email
));
if ($this->check->rowCount())
{
$this->get = $this->check->fetch(PDO::FETCH_ASSOC);
$this->insert = $this->pdo->prepare
("
INSERT INTO account_verifications
(user_id, generated_code, date, time)
VALUES
(:id, :code, CURDATE(), CURTIME())
");
$generatedCode = self::generateCode($salt);
$this->insert->execute(array
(
":id" => $this->get['user_id'],
":code" => $generatedCode
));
$this->check = $this->pdo->prepare("SELECT * FROM account_verifications WHERE user_id = :id AND generated_code = :code");
$this->check->execute(array
(
":id" => $this->get['user_id'],
":code" => $generatedCode
));
if ($this->check->rowCount())
{
$this->get = $this->check->fetch(PDO::FETCH_ASSOC);
mail
(
$email,
'Driptone - Activate your account',
'Hello '.$username.'. you must activate your account before
you can start using your account.
You can activate your account by clicking on the following link:
http://localhost/drip/activate.php?u='.$this->get['user_id'].'&a='.$this->get['generated_code'].'
Thank you,
Driptone.',
'From: noreply@driptone.com'
);
}
else
{
throw new exception ("sHIT Happens!");
}
}
else
{
throw new exception ("An error has occured!");
}
}