Im pretty much confused by $wpdb->prepare. I want to use it to sanitize user input but it turned out that it destroys the query. I cannot imagine that this is how it’s intended to work but I can’t find out what I’m doing wrong. Please be so patient and point me to the solution.
The following code is just a simple example for demonstration purposes just to make it clear what’s going wrong and how. Later there will be user input feeding this query.
When I left out prepare and use sprintf instead this example is working :
global $wpdb;
$mydb = new \wpdb( "My_Login" ,"My_PW" , "My_Custom_DB" ,"localhost"); //wpdb instance for my custom db
$tablename = "books";
$sort_direction = "DESC";
$limit = 5;
$sqlquery = sprintf( "SELECT * FROM %s ORDER BY datum %s LIMIT %d", $tablename, $sort_direction, $limit );
$res = $mydb->get_results( $sqlquery );
echo "<br>".$sqlquery."<br>";
var_dump($res);
The output of var_dump() is a proper array containing the expected result.
The output of $sqlquery is:
SELECT * FROM books ORDER BY datum DESC LIMIT 5
Which is proper SQL.
Now I will use prepare (this is the only changed line):
global $wpdb;
$mydb = new \wpdb( "My_Login" ,"My_PW" , "My_Custom_DB" ,"localhost"); //wpdb instance for my custom db
$tablename = "books";
$sort_direction = "DESC";
$limit = 5;
$sqlquery = $mydb->prepare( "SELECT * FROM %s ORDER BY datum %s LIMIT %d", $tablename, $sort_direction, $limit );
$res = $mydb->get_results( $sqlquery );
echo "<br>".$sqlquery."<br>";
var_dump($res);
The output of var_dump() is NULL
The output of $sqlquery is:
SELECT * FROM 'books' ORDER BY datum 'DESC' LIMIT 5
Where obviously table name and DESC shouldn’t be enclosed in quotation marks. IMO this is the reason why it fails. I double checked that this isn’t related to instancing $wpdb. When I work with $wpdb the escaping result is the same.
What’s going on or what did I wrong? Please help me.