0

我开发了一个通过电子邮件发送激活码的注册系统。如果该用户名已存在,则返回错误“用户名已存在”。

当我在数据库中没有任何用户时,我注册的第一个用户名返回“用户名已存在!” 并自动将用户插入数据库。

但是当我再试一次并且我的数据库中已经有一个用户时,它工作得很好。

那里有什么问题?

注册方法:

   /**
    * 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!");
        }
    }
4

2 回答 2

1

从手册:

PDOStatement::rowCount() returns the number of rows affected by the last DELETE,
INSERT, or UPDATE statement executed by the corresponding PDOStatement object.


If the last SQL statement executed by the associated PDOStatement was a SELECT
statement, some databases may return the number of rows returned by that statement.
However, this behaviour is not guaranteed for all databases and should not be
relied on for portable applications.

由于您不能将其用于选择语句,因此我会使用

$this->check = $this->pdo->prepare("SELECT COUNT(*) FROM users where user_name = :username AND user_email = :email");

然后检查返回的值,而不是使用可能会或可能不会做你认为应该做的事情的函数。

于 2013-05-17T19:32:53.433 回答
0

我发现了问题。

如果我没有任何行,我必须使用

$this->users->rowCount() == 1

因为 rowCount 返回一个字符串。

这解决了我的问题,谢谢大家。

于 2013-05-17T19:46:52.583 回答