Paul Paku
Paul Paku

Reputation: 361

PDO adds the apostrophe to the mySQL query

After years of reading it's time to ask first question :)

My problem is that after migrating the code from mySQLi to PDO we have got a problem as it seems PDO adds the apostrophes to the query.

PHP code goes like that:

$sort   = $_GET['sort']; << table column name (mySQL VARCHAR only columns)

....
$query = 'SELECT * FROM table WHERE xxx > 0';
$query .= ' ORDER BY :sort ASC ;';

$qry_result= $db->prepare($query);  
$qry_result->execute(array(':sort'=>$sort));

mysqli version went smoothly but now queries (mysql log file) looks like this:

SELECT * FROM table where xxx > 0 ORDER BY 'SORT_VAR_VALUE' ASC;
                                           ^  2 problems  ^

So the table is NOT sorted, as sort order (from mySQL point of view) is wrong.

phpinfo() does not get any results for search on "magic" nor "quotes" btw.

Any idea ??

Upvotes: 1

Views: 723

Answers (3)

BrokenBinary
BrokenBinary

Reputation: 7879

The placeholders in PDO statements are for values only. If you want to add actual SQL to the query you need to do it another way.

First, you should sanitize $sort and surround it with backticks in the query.

$sort = preg_replace('/^[a-zA-Z0-9_]/', '', $sort);

Then you could double quote the query string and PHP will replace $sort with it's value for you:

$query = "SELECT * FROM table WHERE xxx > 0 ORDER BY `$sort` ASC";

Or you could replace it with preg_replace like so:

$query = 'SELECT * FROM table WHERE xxx > 0 ORDER BY `:sort` ASC';
$query = preg_replace('/:sort/', $sort, $query, 1);

I would use the preg_replace method because it allows you to reuse the query if you assign the results from preg_replace to another variable instead of overwriting the original variable.

Upvotes: 2

Get Off My Lawn
Get Off My Lawn

Reputation: 36299

by default pdo binds values as strings.

To fix this you will want to check that the column is actually a valid name and then add it to the query, you can do it the following way:

function validName($string){
    return !preg_match("/[^a-zA-Z0-9\$_\.]/i", $string);
}

if(validName($sort)){
    $db->prepare("SELECT * FROM table where xxx > 0 ORDER BY $sort ASC");
}

Upvotes: 2

Guillermo
Guillermo

Reputation: 791

With PDO it's not possible to bind other things that variables in the WHERE statement. So you have to hard code the names of the columns you order by. See How do I set ORDER BY params using prepared PDO statement? or Can PHP PDO Statements accept the table or column name as parameter? for further explanations.

Upvotes: -1

Related Questions