views:

42

answers:

2

When I am using a PDO prepared statement, and use it to plug in a table name to the query it fails, a quick example:

$stmt = $dbh->prepare("CREATE TABLE ? (id foo, int bar,...)");
$stmt->execute(Array('table_foobar'));

All it does is replaces ? with 'table_foobar', the single quotes don't allow creation of the table for me!

I end up needing to do a sprintf on TOP of the prepared statement to add in a predefined table name.

What on earth am I missing here?

+2  A: 

I can find nothing clear in the manual, but looking at the User Contributed Notes, the use of parameters is intended for actual values only, not table names, field names etc.

Normal string concatenation should (and can) be used.

$tablename = "tablename";
$stmt = $dbh->prepare("CREATE TABLE `$tablename` (id foo, int bar,...)");
Pekka
That's what I am always talking about (and bored everyone to death, hehe) when someone claims that "prepared statements are 100% safe"
Col. Shrapnel
@Col true - if you *need* to use a dynamic table name, it should be escaped somehow - for which PDO, if I see correctly, has no explicit `escape` function any more! Because, well, you don't need that anymore. Because, that's what you have parametrized queries for.
Pekka
I kept using `sprintf` because I defined the table name in a `define`, I changed it to a variable to be done with it.
John
+3  A: 

If you are creating a table dynamically, that most likely means you do not understand relational database ideology and as a result doing something wrong.
Just create all the tables at application setup from ready made dump and do not create any tables at runtime.

No need to use dynamic table name at all.

Col. Shrapnel
Good point and good to follow wherever possible, but I can see one use case for dynamic table names: Redistributable applications that allow for a user-specified prefix `appname_tablename` to fit multiple installations / applications into one database - sometimes necessary in hosted environments.
Pekka
It's part of an application setup, I purely meant the table name to be set up by the webmaster, and unfortunately chose defines, hense the problem with needing sprintf. Fixed now with using variable.
John
It is correct, to build all your tables in the beginning and not dynamically. But it's more general case. For example with a select-statement you would also have this problems. `SELECT * FROM ?` wouldn't work either, so the problem will even persist, if he wouldn't create tables dynamically :)
faileN
@faileN `SELECT * FROM ?` indicates bad design either. However `ORDER BY ?` is more sensible case. Hardcoding all possible options is the solution.
Col. Shrapnel