As noted here (thanks @YourCommonSense), you can't use a parameter as a table name; and if you do, one of two things will happen:
- With proper prepared statements, the prepared-statement module will throw an exception (and quite rightly so, as you've asked it to do the impossible).
- With emulated prepared statements, the parameter will be blindly escaped, single-quoted, and substituted in, causing an SQL syntax error. This is what's happened here.
That's the problem. As for solutions:
- Reevaluate your database design. Do you really need to split data across different tables like that? If not, combine the relevant data into a single table, and query accordingly.
If you're happy with the design (or can't change it), you'll need an ugly insecure hack like the following:
function get_data($tablename, $acceptable_tablenames = array()) { /* $acceptable_tablenames is an array of strings, containing * table names that you'll accept. It's your job to make sure * these are safe; this is a much easier task than arbitrary * sanitization. */ if (array_search($tablename, $acceptable_tablenames, true) === FALSE) { throw new Exception("Invalid table name"); /* Improve me! */ } else { /* your try/catch block with PDO stuff in it goes here * make sure to actually return the data */ } }
Call it as
get_data($table, array("my_datatable_1", "my_datatable_2"))
. Credit to the post linked to at the start of my answer for inspiration.