php - 注册时将用户 ID 插入到另一个表中

标签 php mysql sql pdo insert

我有一个可以捕获电子邮件和密码的注册表单。提交表单后,它将在我的用户表中添加 AUTO_INCRMENT 用户 ID、电子邮件和密码。在同一提交过程中,我想将在用户表中创建的 ID 添加到 users_preferences 表中。

这是我目前拥有的:

require("config.php");
if(!empty($_POST)) 
{ 
    // Ensure that the user fills out fields 
    if(empty($_POST['username'])) 
    { die("Please enter a username."); }
    if(!filter_var($_POST['username'], FILTER_VALIDATE_EMAIL)) 
    { die("Invalid E-Mail Address"); }  
    if(empty($_POST['password'])) 
    { die("Please enter a password."); } 

    // Check if the username is already taken
    $query = " 
        SELECT 
            1 
        FROM users 
        WHERE 
            username = :username 
    "; 
    $query_params = array( ':username' => $_POST['username'] ); 
    try { 
        $stmt = $db->prepare($query); 
        $result = $stmt->execute($query_params); 
    } 
    catch(PDOException $ex){ die("Failed to run query: " . $ex->getMessage()); } 
    $row = $stmt->fetch(); 
    if($row){ die("This email address is already registered"); } 


    // Add row to database         
    $query = "             
        BEGIN;
        INSERT INTO users ( 
            username, 
            password, 
            salt 
        ) VALUES ( 
            :username, 
            :password, 
            :salt
        ) ;
        INSERT INTO user_preferences (
            user_id
        ) VALUES (
            $user_id
        );
        COMMIT;
    "; 
     $user_id = mysql_insert_id();

    // Security measures
    $salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647)); 
    $password = hash('sha256', $_POST['password'] . $salt); 
    for($round = 0; $round < 65536; $round++){ $password = hash('sha256', $password . $salt); } 
    $query_params = array( 
        ':username' => $_POST['username'], 
        ':password' => $password, 
        ':salt' => $salt 
    ); 
    try {  
        $stmt = $db->prepare($query); 
        $result = $stmt->execute($query_params); 
    } 
    catch(PDOException $ex){ die("Failed to run query: " . $ex->getMessage()); } 
    header("Location: index.php"); 
    die("Redirecting to index.php"); 
} 

用户的注册将经过并将数据添加到数据库中,但不会将任何数据添加到 user_preferences 表中。我如何才能将最后一个用户 ID 添加到第二个表中?

最佳答案

我看到的问题是,您试图将 $user_id 的值放入查询中,但它只会在下一个命令行中收到一个值(尽管您不是实际上运行第一个查询,您只是想获取最后插入的 id)。

您应该首先运行 INSERT INTO users... 查询,然后检索最后插入的 ID,然后运行第二个查询 (INSERT INTO user_preferences...) .

另外假设您使用的是 PDO,最后插入的 id 在您的上下文中应该是 $db->lastInsertId()

** 更新

好吧,在不改变你的代码的情况下,只是稍微重构一下,你应该尝试这样的事情:

function checkDataValidity(){
    if(empty($_POST['username'])){
        throw new Exception("Please enter a username."); 
    }
    if(!filter_var($_POST['username'], FILTER_VALIDATE_EMAIL)){ 
        throw new Exception("Invalid E-Mail Address"); 
    }  
    if(empty($_POST['password'])){ 
        throw new Exception("Please enter a password."); 
    } 
}

function doesUserExist($dbHandler){
    $query  = " SELECT 1 FROM users WHERE username = :username;"; 
    $query_params = array( ':username' => $_POST['username'] ); 
    $stmt   = $dbHandler->prepare($query);
    $result = $stmt->execute($query_params); 

    if ($stmt->rowCount() > 0){
        throw new Exception('This email address is already registered');
    }
}

function insertNewUser($dbHandler){
    try{
        $salt     = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647)); 
        $password = hash('sha256', $_POST['password'] . $salt); 
        for($round = 0; $round < 65536; $round++){ 
            $password = hash('sha256', $password . $salt); 
        } 
        $query_params = array( 
            ':username' => $_POST['username'], 
            ':password' => $password, 
            ':salt' => $salt 
        ); 

        $dbHandler->beginTransaction();
        $query = "INSERT INTO users (username, password, salt) VALUES ( :username,  :password, :salt );";
        $stmt = $dbHandler->prepare($query); 
        $result = $stmt->execute($query_params); 

        $newUserId = $dbHandler->lastInsertId();
        $dbHandler->commit();

    }catch(Exception $dbException){
        $dbHandler->rollback();
        $newUserId = NULL;
    }

    return $newUserId;
}

function insertUserPreference($dbHandler, $userId){
    $query_params = array( 
        ':user_id' => $userId
    );
    try{
        $dbHandler->beginTransaction();
        $query = "INSERT INTO user_preferences ( user_id ) VALUES ( :user_id );"; 
        $stmt = $dbHandler->prepare($query); 
        $result = $stmt->execute($query_params); 

        $dbHandler->commit();

    }catch(Exception $dbException){
        $dbHandler->rollback();
    }
}

require("config.php");
if(!empty($_POST)) 
{ 
    try{
        checkDataValidity();
        doesUserExist($db);
        $newUserId = insertNewUser($db);

        if (!is_null($newUserId)){
            insertUserPreference($db, $newUserId);
        }else{
            throw new Exception('Error inserting user');
        }

        header("Location: index.php"); 
        die("Redirecting to index.php"); 
    } catch (Exception $e){
        echo 'The following error occured: <br/>'.$e->getMessage();
    }   
} 

不要让这些更改让您感到困惑 - 我只是重新排列了您的代码以使其更易于阅读。上面通过将“用户插入”移动到一个函数中解决了最初的问题,如果插入成功,我们返回新的 ID,否则返回 null 值,并且我们还将查询的后半部分移动到它自己的函数中。

关于php - 注册时将用户 ID 插入到另一个表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25391437/

相关文章:

php - 保存在 Opencart 模块后,我的 HTML 内容消失了

php - 按 transaction_code 显示数据库组中的数据

php - 使用 Laravel 4 的 URL 片段

mysql - 如何使此 sql INSERT SELECT 查询在空表上工作?

C++:将 SQL 查询的结果集转换为 JSON

php - 删除 Thrift 生成的 PHP 文件类名处的第一个 "\"

mysql - SQL内连接合并为一行

php - 在 MySQL 中合并 2 个表并创建一个新表

php - 查找MySQL查询结果中某个字段的最大值

android - 如何在 Android 中干净地处理多个数据库表?