Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

php

mysql

pdo

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:

   try {
        $cnx = new PDO($dsn,$dbuser,$dbpass);   
        $cnx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $cnx->beginTransaction();
        $cnx->query("SELECT * FROM users WHERE username=$escaped_input");
        $cnx->query("SELECT * FROM othertable WHERE some_column=$escaped_input_2");

        $cnx->commit();
    }

    catch (Exception $e){
           $cxn->rollback();
           echo "an error has occured";

    }

I would like to incorporate the query as one would with a prepared statement:

$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));

How can I achieve that?

Edit

I get this error:

PHP Parse error: syntax error, unexpected T_CATCH

Here is my updated code:

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 $stmt->userid;

}

catch(Exception $e) { 
    if (isset($cnx)) 
        $cnx->rollback();
       echo "Error:  " . $e; 
    }
like image 761
alexx0186 Avatar asked May 17 '12 19:05

alexx0186


People also ask

Can we use prepared statement for select query in PHP?

You must always use prepared statements for any SQL query that would contain a PHP variable. To do so, always follow the below steps: Create a correct SQL SELECT statement. Test it in mysql console/phpmyadmin if needed.

What is prepared statement explain the advantage of using prepared statement with PHP and Mysql with an example?

A prepared statement is a feature used to execute the same (or similar) SQL statements repeatedly with high efficiency. Prepared statements basically work like this: Prepare: An SQL statement template is created and sent to the database. Certain values are left unspecified, called parameters (labeled "?").

What is the use of prepared statement in PHP?

A prepared statement or a parameterized statement is used to execute the same statement repeatedly with high efficiency and protect against SQL injections. The prepared statement execution consists of two stages: prepare and execute. At the prepare stage a statement template is sent to the database server.

What is $STMT in PHP MySQLi?

" $stmt " obviously (I think) stands for "statement". As a variable name it's arbitrary, you can name that variable anything you want. $stmt is just rather idiomatic. A prepared statement as such is a database feature.


2 Answers

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"?

like image 195
paulsm4 Avatar answered Sep 19 '22 11:09

paulsm4


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; 
    }
}
like image 44
Jeroen Avatar answered Sep 19 '22 11:09

Jeroen