[英]PHP PDO MySQL Transaction code structure
我正在嘗試使用PHP / PDO在MySQL中設置我的第一筆交易...
我有一個簡單的問題,確定上一個查詢是否成功的最佳方法是什么? 這是我現在擁有的,但是我寧願找到一種使用if語句測試查詢的方法。
這幾乎是模擬代碼,試圖獲得有效的模型。.我知道$ results不能有效地測試任何東西的好壞。.當時間到來時,我有更多的地方可以作為實際交易的占位符..
if ($_POST['groupID'] && is_numeric($_POST['groupID'])) {
$sql = "SET AUTOCOMMIT=0";
$dbs = $dbo->prepare($sql);
$dbs->execute();
$sql = "START TRANSACTION";
$dbs = $dbo->prepare($sql);
$dbs->execute();
$sql = "DELETE FROM users_priveleges WHERE GroupID=:groupID";
$dbs = $dbo->prepare($sql);
$dbs->bindParam(":groupID", $_POST['groupID'], PDO::PARAM_INT);
$dbs->execute();
try {
$sql = "DELETE FROM groups WHERE GroupID=:groupID LIMIT 1";
$dbs = $dbo->prepare($sql);
$dbs->bindParam(":groupID", $_POST['groupID'], PDO::PARAM_INT);
$dbs->execute();
$results["error"] = null;
$results["success"] = true;
try {
$sql = "DELETE FROM users WHERE Group=:groupID";
$dbs = $dbo->prepare($sql);
$dbs->bindParam(":groupID", $_POST['groupID'], PDO::PARAM_INT);
$dbs->execute();
$results["error"] = null;
$results["success"] = true;
$sql = "COMMIT";
$dbs = $dbo->prepare($sql);
$dbs->execute();
}
catch (PDOException $e) {
$sql = "ROLLBACK";
$dbs = $dbo->prepare($sql);
$dbs->execute();
$results["error"] = "Could not delete associated users! $e";
$results["success"] = false;
}
}
catch (PDOException $e)
{
$sql = "ROLLBACK";
$dbs = $dbo->prepare($sql);
$dbs->execute();
$results["error"] = "COULD NOT REMOVE GROUP! $e";
$results["success"] = false;
}
}
一般常識:不要使用bindParam()
除非你使用一個程序,修改參數的值。因此, use bindValue()
bindParam()接受參數值作為引用變量。 這意味着您不能執行$stmt->bindParam(':num', 1, PDO::PARAM_INT);
-引發錯誤。 另外,PDO具有自己的控制交易的功能,您無需手動執行查詢。
我稍微重寫了您的代碼,以闡明如何使用PDO:
if($_POST['groupID'] && is_numeric($_POST['groupID']))
{
// List the SQL strings that you want to use
$sql['privileges'] = "DELETE FROM users_priveleges WHERE GroupID=:groupID";
$sql['groups'] = "DELETE FROM groups WHERE GroupID=:groupID"; // You don't need LIMIT 1, GroupID should be unique (primary) so it's controlled by the DB
$sql['users'] = "DELETE FROM users WHERE Group=:groupID";
// Start the transaction. PDO turns autocommit mode off depending on the driver, you don't need to implicitly say you want it off
$pdo->beginTransaction();
try
{
// Prepare the statements
foreach($sql as $stmt_name => &$sql_command)
{
$stmt[$stmt_name] = $pdo->prepare($sql_command);
}
// Delete the privileges
$stmt['privileges']->bindValue(':groupID', $_POST['groupID'], PDO::PARAM_INT);
$stmt['privileges']->execute();
// Delete the group
$stmt['groups']->bindValue(":groupID", $_POST['groupID'], PDO::PARAM_INT);
$stmt['groups']->execute();
// Delete the user
$stmt['users']->bindParam(":groupID", $_POST['groupID'], PDO::PARAM_INT);
$stmt['users']->execute();
$pdo->commit();
}
catch(PDOException $e)
{
$pdo->rollBack();
// Report errors
}
}
我不會准備和執行交易報表。 我會使用PDO :: beginTransaction() , PDO :: commit()和PDO :: rollback() 。
如果發生錯誤,則PDO :: prepare()和PDO :: execute()返回FALSE,否則,如果您設置setAttribute(PDO :: ATTR_ERRMODE,PDO :: ERRMODE_EXCEPTION),它們將拋出PDOException。
在異常處理程序中,應檢查PDO :: errorInfo()並報告錯誤的性質。 最佳做法是記錄原始錯誤信息,但為用戶提供更友好的消息。
不要在用戶界面中回顯文字錯誤消息-這可能會使用戶對SQL查詢和架構有不當的了解。
PDO語句的execute()
成功返回TRUE,失敗則返回FALSE,因此您可以在if語句中測試前一個execute()
的返回值。
$pdo_result = $dbs->execute();
if ($pdo_result) {
// handle success
} else {
// handle failure
// you can get error info with $dbs->errorInfo();
}
就是說,正如@Bill Kerwin正確指出的那樣(他的回答是我完全贊成,因為它是完全正確的),最好使用PDO::beginTransaction()
, PDO::commit()
和PDO::rollback()
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.