Tôi có một trang đăng ký và về cơ bản tôi cần dữ liệu được chèn vào 4 bảng. Tôi mới đến PDO và đang bối rối về điều gì đó.Giao dịch PDO PHP?
Về cơ bản nếu bất kỳ chèn nào không thành công, tôi không muốn bất kỳ thứ gì được thêm vào cơ sở dữ liệu, điều đó dường như đủ đơn giản.
Sự nhầm lẫn của tôi là, trước tiên tôi cần chèn tên người dùng, email, mật khẩu, v.v. vào bảng users
để tôi có thể nhận được (không biết chắc) bằng cách sử dụng PDO mà uid MySQL đã cung cấp cho người dùng của tôi (tự động tăng lên bởi mysql). Tôi cần người dùng uid MySQL đã cho người dùng của tôi cho các bảng khác như các bảng khác cần uid để tất cả mọi thứ được liên kết đúng với nhau. Bảng của tôi là InnoDB và tôi có khóa ngoài từ users_profiles (user_uid), users_status (user_uid), users_roles (user_uid) đến users.user_uid để chúng được liên kết với nhau.
Nhưng đồng thời tôi muốn đảm bảo rằng nếu ví dụ sau khi dữ liệu được chèn vào bảng users
(vì vậy tôi có thể nhận được uid MySQL đã cung cấp cho người dùng) rằng nếu bất kỳ chèn nào khác không thể xóa dữ liệu đã được đưa vào bảng users
.
Tôi nghĩ tốt nhất là tôi nên hiển thị mã của mình; Tôi đã nhận xét ra mã và đã giải thích trong mã mà có thể làm cho nó dễ hiểu hơn.
// 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;
}
Tôi mới tham gia PDO và có thể có lỗi hoặc vấn đề ở trên mà tôi chưa thông báo vì tôi chưa thể kiểm tra cho đến khi tôi tìm ra vấn đề của mình.
1) Tôi cần phải biết làm thế nào tôi có thể chèn dữ liệu người dùng trong bảng người dùng đầu tiên vì vậy tôi có thể nhận được MySQL uid cho người dùng của tôi
2) Sau đó lấy uid như tôi cần nó cho các bảng khác
3) Nhưng đồng thời nếu truy vấn không thành công vì bất kỳ lý do nào sau khi chèn vào bảng người dùng thì dữ liệu cũng sẽ bị xóa khỏi bảng người dùng.
UPDATE:
tôi cập nhật mã trên để phản ánh những thay đổi đã được cung cấp bởi các thành viên hữu ích.
a) Đặt '$ dbh-> beginTransaction();' và dòng trước đó bên ngoài khối try/catch - bạn không thể khôi phục bất kỳ thứ gì cho đến khi giao dịch được bắt đầu. b) Điều gì không làm việc với điều này? Chỉ cần sử dụng lastInsertId như bình thường. – Niko
@Niko, tôi sẽ thực hiện việc này trong giây lát, cảm ơn bạn phplover – PHPLOVER
@Niko, tôi đã chỉnh sửa mã ở trên để phản ánh thay đổi bạn đã nói, tôi có thể hỏi tại sao không thể '$ dbh-> beginTransaction();' khối thử cũng? không hoàn toàn hiểu rằng bit, nhờ phplover – PHPLOVER