web-dev-qa-db-fra.com

PHP Transactions AOP?

J'ai une page d'inscription et j'ai essentiellement besoin de données insérées dans 4 tableaux. Je suis nouveau sur PDO et je suis confus à propos de quelque chose.

Fondamentalement, si l'une des insertions échoue, je ne veux rien ajouter à la base de données, cela semble assez simple.

Ma confusion est que je dois d'abord insérer le nom d'utilisateur, l'adresse e-mail, le mot de passe, etc. dans ma table users afin que je puisse obtenir (je ne sais pas comment) en utilisant PDO l'uid MySQL a donné à mon utilisateur (incrémenté automatiquement par mysql) . J'ai besoin de l'uid utilisateur MySQL donné à mon utilisateur pour les autres tables car les autres tables ont besoin de l'uid pour que tout soit correctement lié. Mes tables sont InnoDB et j'ai des clés étrangères allant de users_profiles (user_uid), users_status (user_uid), users_roles (user_uid) à users.user_uid afin qu'ils soient tous liés ensemble.

Mais en même temps, je veux m'assurer que si, par exemple, après que des données sont insérées dans la table users (afin que je puisse obtenir l'uid que MySQL a donné à l'utilisateur), si l'une des autres insertions échoue, elle supprime les données qui a été inséré dans la table users.

Je pense qu'il vaut mieux que je montre mon code; J'ai commenté le code et l'ai expliqué dans le code, ce qui peut le rendre plus facile à comprendre.

// Begin our transaction, we need to insert data into 4 tables:
// users, users_status, users_roles, users_profiles
// connect to database
$dbh = sql_con();

// begin transaction
$dbh->beginTransaction();

try {

    // this query inserts data into the `users` table
    $stmt = $dbh->prepare('
                        INSERT INTO `users`
                        (users_status, user_login, user_pass, user_email, user_registered)
                        VALUES
                        (?, ?, ?, ?, NOW())');

    $stmt->bindParam(1, $userstatus,     PDO::PARAM_STR);
    $stmt->bindParam(2, $username,       PDO::PARAM_STR);
    $stmt->bindParam(3, $HashedPassword, PDO::PARAM_STR);
    $stmt->bindParam(4, $email,          PDO::PARAM_STR);
    $stmt->execute();

    // get user_uid from insert for use in other tables below
    $lastInsertID = $dbh->lastInsertId();

    // this query inserts data into the `users_status` table
    $stmt = $dbh->prepare('
                        INSERT INTO `users_status`
                        (user_uid, user_activation_key)
                        VALUES
                        (?, ?)');

    $stmt->bindParam(1, $lastInsertID,     PDO::PARAM_STR);
    $stmt->bindParam(2, $activationkey,    PDO::PARAM_STR);
    $stmt->execute();

    // this query inserts data into the `users_roles` table
    $stmt = $dbh->prepare('
                        INSERT INTO `users_roles`
                        (user_uid, user_role)
                        VALUES
                        (?, ?)');

    $stmt->bindParam(1, $lastInsertID,      PDO::PARAM_STR);
    $stmt->bindParam(2, SUBSCRIBER_ROLE,    PDO::PARAM_STR);
    $stmt->execute();

    // this query inserts data into the `users_profiles` table
    $stmt = $dbh->prepare('
                        INSERT INTO `users_profiles`
                        (user_uid)
                        VALUES
                        (?)');

    $stmt->bindParam(1, $lastInsertID,      PDO::PARAM_STR);
    $stmt->execute();

    // commit transaction
    $dbh->commit();

} // any errors from the above database queries will be catched
catch (PDOException $e) {
    // roll back transaction
    $dbh->rollback();
    // log any errors to file
    ExceptionErrorHandler($e);
    require_once($footer_inc);
    exit;
}

Je suis nouveau sur PDO et il y a peut-être des erreurs ou des problèmes ci-dessus que je n'ai pas encore remarqués car je ne peux pas encore tester avant d'avoir résolu mon problème.

1) Je dois d'abord savoir comment insérer les données des utilisateurs dans le tableau des utilisateurs afin que je puisse obtenir l'uid que MySQL a donné à mon utilisateur

2) Puis récupérez l'uid comme j'en ai besoin pour les autres tables

3) Mais en même temps, si une requête échoue pour une raison quelconque après avoir inséré dans la table des utilisateurs, les données sont également supprimées de la table des utilisateurs.

MISE À JOUR:

J'ai mis à jour le code ci-dessus pour refléter les changements proposés par les membres utiles.

36
PHPLOVER

Cette fonction renvoie la clé primaire de l'enregistrement juste inséré: PDO :: lastInsertId Vous en aurez besoin pour NEED_USERS_UID_FOR_HERE paramètre. Utilisez-le juste après l'instruction INSERT.

Depuis que vous avez commencé une transaction, les données ne seront insérées dans aucune table si une erreur se produit à condition d'utiliser le moteur InnoDB pour vos tables MySQL (MyISAM ne prend pas en charge les transactions).

18