0
votes

I've been using ADOdb for many years as my database abstraction and query caching layer. Lately I switched to prepared statements, mostly for security, and became curious about the way they are (or are not) implemented.

Quote from the documentation for the Prepare method: “Returns an array containing the original sql statement in the first array element; the remaining elements of the array are driver dependent. If there is an error, or we are emulating Prepare( ), we return the original $sql string.

Testing the statement variable with:

$stmt = $db->Prepare("SELECT * FROM pages WHERE id = ?");
print_r($stmt);

On connections opened with ‘mysql’ or ‘mysqli’ parameter only the original query string is returned – meaning the prepared statement is emulated, I guess. A connection opened with ‘pdo_mysql’ returns (from print_r()):

Array (
    [0] => SELECT * FROM pages WHERE id = ? 
    [1] => PDOStatement Object ([queryString]=>SELECT * FROM pages WHERE id = ?) 
) 

Can I take this as a definite proof of a real prepared statement? If not, does anybody know of a quick and dirty way to check server-side (something to look for in the query log, or maybe in MySQLProxy)? I tried to read the library source, but got lost halfway...

1

1 Answers

0
votes

Can I take this as a definite proof of a real prepared statement

As documentations says, if you try to prepare statement using driver that does not support prepared statements, only given query is returned, otherwise array with query as first element. So to check if prepared statement is going to be emulated just check if $stmt is array. I assume you wouldn't try to prepare by passing an array, so this one should be enough:

$stmt = $db->Prepare("SELECT * FROM pages WHERE id = ?");
if(is_array($stmt)){
    //prepared
}
else{
    //emulated
}

If you are confused why mysqli driver returns SQL despite mysqli driver supporting prepared statements, it's explained in line 662 of drivers/adodb-mysqli.inc.php:

// Prepare() not supported because mysqli_stmt_execute does not return a recordset, but
// returns as bound variables.