簡體   English   中英

PHP PDO MySQL事務代碼結構

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM