@Diego is correct, you cannot use an SQL parameter for a table name, column name, SQL keyword, list of value (like in an IN() predicate), or any other expression.
SELECT :column FROM table -- NO, unless you want to select a constant string
SELECT * FROM :table -- NO
SELECT * FROM table WHERE column IN (:list) -- NO
SELECT * FROM table ORDER BY :column -- NO
SELECT * FROM TABLE ORDER BY column :asc_or_desc -- NO
Basically, remember this rule: if you could put a constant value (e.g. a quoted string, a date, or an integer) in place of the SQL parameter, it's a legitimate use of a parameter. Otherwise, no.
SELECT :string FROM table -- OK, but returns value of :string for every row
SELECT * FROM table WHERE column = :string -- OK
SELECT * FROM table WHERE column IN (:x, :y, :z) -- OK, one parameter per value
Also when programming PDO, you should always check the return value of prepare() and execute(). They will return false on error, and you should write your code to detect this and respond appropriately (i.e. log error, display error page, give user another chance, etc.)
$stmt = $conn->prepare("SELECT * FROM :type"); // illegal use of parameter
if ($stmt === false) {
// check $pdo->errorInfo(), see documentation
}
$stmt->bindParam(':type', $type);
$status = $stmt->execute();
if ($status === false) {
// check $stmt->errorInfo(), see documentation
}
You may even want to check return values for other PDO functions. See the documentation, many of them return false on error.