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?
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;
}
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.
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 "?").
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.
" $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.
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"?
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With