2012-04-14 23 views
29

Mam stronę rejestracji i zasadniczo potrzebuję danych wstawionych do 4 tabel. Jestem nowy w PDO i jestem zdezorientowany.Operacje PHP PDO?

Zasadniczo, jeśli którykolwiek z insertów nie działa, nie chcę niczego dodawać do bazy danych, wydaje się to dość proste.

Moje zamieszanie polega na tym, że muszę najpierw wstawić nazwę użytkownika, adres e-mail, hasło itp. W mojej tabeli users, aby uzyskać (nie wiem jak) przy użyciu PDO, którego uid MySQL podał mojemu użytkownikowi (auto inkrementowane przez mysql). Potrzebuję użytkownika uid MySQL dał mojemu użytkownikowi inne tabele, ponieważ inne tabele wymagają uid, więc wszystko jest poprawnie połączone razem. Moje tabele są InnoDB i mam klucze obce przechodzące od users_profiles (user_uid), users_status (user_uid), users_roles (user_uid) do users.user_uid, więc są one wszystkie połączone razem.

Ale jednocześnie chcę się upewnić, że jeśli na przykład po wstawieniu danych w tabeli users (tak, że mogę uzyskać identyfikator użytkownika MySQL), jeśli którykolwiek z innych insertów nie powiedzie się, to usuwa dane, które został wstawiony do tabeli users.

Uważam, że najlepiej pokazać kod; Skomentowałem kod i wyjaśniłem w kodzie, który może ułatwić zrozumienie.

// 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; 
} 

Jestem nowy w PDO i mogą pojawić się błędy lub problemy, których jeszcze nie zauważyłem, ponieważ nie mogę jeszcze przetestować, dopóki nie rozwiążę mojego problemu.

1) Muszę wiedzieć, w jaki sposób można wstawić dane użytkowników w tabeli użytkowników pierwszy więc mogę dostać uid MySQL dałem użytkownikowi

2) Następnie uzyskać UID jak muszę go dla innych stołach

3) Ale w tym samym czasie, jeśli zapytanie nie powiedzie się z jakiegoś powodu po wstawieniu do tabeli użytkowników, dane są również usuwane z tabeli użytkowników.

UPDATE:

I uaktualniony kod powyżej w celu uwzględnienia zmian, które było oferowane przez pomocnych członków.

+3

a) Umieść '$ dbh-> beginTransaction();' i linię przed tym poza blokiem try/catch - nie możesz przywrócić niczego, dopóki transakcja się nie rozpocznie. b) Co z tym nie działa? Po prostu użyj lastInsertId jak zwykle. – Niko

+0

@Niko, zrobię to za chwilę, dziękuję, phplover – PHPLOVER

+0

@Niko, redagowałem kod powyżej, aby odzwierciedlić zmianę, którą powiedziałeś, czy mogę zapytać, dlaczego nie można "$ dbh-> beginTransaction();" blok try również? nie całkiem rozumiem, że trochę, dzięki phplover – PHPLOVER

Odpowiedz

18

Ta funkcja zwraca klucz podstawowy właśnie wstawionego rekordu: PDO::lastInsertId Będzie potrzebny dla parametru NEED_USERS_UID_FOR_HERE. Użyj go zaraz po instrukcji INSERT.

Po rozpoczęciu transakcji dane nie zostaną wstawione do żadnej tabeli, jeśli wystąpi błąd, pod warunkiem, że do tabel MySQL zostanie użyty silnik InnoDB (MyISAM nie obsługuje transakcji).

+0

dziękuję, myślę, że rozumiem to teraz, umieszczam '$ dbh-> lastInsertId();' po instrukcji INSERT (zobacz edytowany kod w oryginalnym wpisie), teraz mam ostatni identyfikator wstawki robiący to, co powiedziałeś powyżej, jak czy mam teraz dostęp do ostatniego identyfikatora wstawiania, aby umieścić go w innych zapytaniach "NEED_USERS_UID_FOR_HERE"? przepraszam, jestem nowy w PDO, więc wciąż to rozumiem, dziękuję, phplover – PHPLOVER

+0

Przepraszam, że mógłbym wyjaśnić to nieco lepiej, czy po prostu przypisuję zmienną do '$ dbh-> lastInsertId();' tak, że staje się czymś w rodzaju '$ lastInsertID = $ dbh-> lastInsertId(); 'a następnie Gdzie jest napisane' NEED_USERS_UID_FOR_HERE' po prostu zamienia to na '$ lastInsertID'? dzięki phplover – PHPLOVER

+2

Tak. Po prostu przechowuj go jako zmienną i używaj go w dalszych zapytaniach. Jeśli transakcja się nie powiedzie, nie zostanie zapisana do bazy danych. –