I was looking for answer for last 3 hours, and i don't know what to do. Here is the code:
function get_data($tablename)
{
try
{
$conn = $this->conn();
$stmt = $conn->prepare("SELECT * FROM :tablename ORDER BY id");
$stmt->bindParam(':tablename', $tablename, PDO::PARAM_STR);
$stmt->execute();
return $stmt;
}
catch (Exception $e)
{
echo "ERROR:" . $e->getMessage();
}
}
And here is the error:
ERROR:SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''products' ORDER BY id' at line 1
What I've done wrong?...
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:
That's the problem. As for solutions:
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.