0

So I am having this strange issue with PDO, in that queries with bound variables are not executing properly for some reason. Let me show some code:

$conn = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pwd);
$sth=$conn->prepare("select count(*) from article");
$sth->execute();
var_dump($sth->fetchColumn());

This will print out the correct number of entries in the table "article".

However, if we change it slightly, by making the table a named parameter instead of a constant:

$conn = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pwd);
$sth=$conn->prepare("select count(*) from :article");
$sth->execute(array(":article"=>"article"));
var_dump($sth->fetchColumn());

This will print a boolean false. Both statements should return the same result, but I have no idea why the second one is not working. I suspect I have a typo somewhere, but I checked several times, and I don't see any issue. Anyone have any idea?

Ermir
  • 1,391
  • 11
  • 25

1 Answers1

3

Not possible. You're trying to use a placeholder for a tablename. This is not permitted. placeholders can only replace values.

SELECT count(*) FROM :table WHERE field=:article
                     ^^^^^^--illegal    ^^^^^^^^--legal

For this, you'll have to use old-fashion string building:

$table = "article";
$sth=$conn->prepare("select count(*) from $table");

which then re-opens the SQL injection attack vulnerability, because you're now directly inserting external data into an SQL string.

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • I am moving an internal project to from mysql() to PDO just to avoid SQL injections. The main danger is from the search queries, which PDO should be able to parametrize. However, the app is not vunerable to SQL injections, even if I use string concatenations, because it's a value that is never touched by the user, so I should be safe. Does the table name placeholder restriction apply to JOINs as well, or just to FROM clauses? I would think yes, but I will check to be sure. – Ermir Mar 03 '14 at 15:00