How can I use prepared statements combined with Transactions with PHP?

后端 未结 3 812
耶瑟儿~
耶瑟儿~ 2020-12-31 19:51

My goal is to use a transaction and a prepared statement simultaneously, to achieve both integrity of data, and prevention of SQL injection.

I have this:

<         


        
相关标签:
3条回答
  • 2020-12-31 19:56

    Just call "execute" after you call "beginTransaction".

    Where you call "prepare" doesn't really matter.

    Here's a complete example:

    http://php.net/manual/en/pdo.begintransaction.php

    EXAMPLE:

     try {
        $cnx = new PDO($dsn,$dbuser,$dbpass);   
        $cnx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
        $cnx->beginTransaction();
    
        $stmt=$cxn->prepare("SELECT * FROM users WHERE username=?");
        $stmt->execute(array($user_input));
    
        $stmt_2=$cxn->prepare("SELECT * FROM othertable WHERE some_column=?");
        $stmt_2->execute(array($user_input_2));
    
        $cnx->commit();
      }
      catch (Exception $e){
        $cxn->rollback();
        echo "an error has occurred";
      }
    

    PS: 1) I'm assuming, of course, that $user_input and $user_input_2 are available immediately. You don't want your transaction hanging open unnecessarily long ;)

    2) Based on your comment reply above, I think you might be confusing "execute" and "begin tran/commit". Please look at my link.

    3) Do you even need a transaction? You're just doing two "select's".

    4) Finally, why not do one "join" (or union, if compatible) instead of two "select's"?

    0 讨论(0)
  • 2020-12-31 20:03
    try 
    {
        $cnx = new PDO ($dsn,$dbuser,$dbpass);   
        $cnx->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
        $cnx->beginTransaction ();
    
        $stmt = $cnx->prepare ("SELECT * FROM users WHERE username=?");
        $stmt->execute(array($username));
    
        $cnx->commit();
    
        while ($row = $stmt->fetch (PDO::FETCH_OBJ)){
            echo $row->userid;
        }
    }
    
    catch (Exception $e) { 
        if (isset ($cnx)) 
            $cnx->rollback ();
           echo "Error:  " . $e; 
        }
    }
    
    0 讨论(0)
  • 2020-12-31 20:14

    Did you mean this?

    try {
        $cnx = new PDO($dsn,$dbuser,$dbpass);   
        $cnx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
        $cnx->beginTransaction();
        $stmt=$cnx->prepare("
            SELECT * FROM users, othertable 
            WHERE users.username=? 
            AND othertable.some_column=?");
    
        $stmt->execute(array($user_input,$user_input_2));
    
        $cnx->commit();
    }
    catch (Exception $e){
           $cnx->rollback();
           echo "an error has occured";
    }
    

    That is assuming that the two tables data does not have duplicate field names, otherwise you're going to have to use:

    SELECT users.field1 as u_field1, othertable.field1 as o_field1 FROM users, othertable 
    WHERE users.username=? 
    AND othertable.some_column=?
    
    0 讨论(0)
提交回复
热议问题