Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can PHP PDO Statements accept the table or column name as parameter?

Tags:

php

pdo

Why can't I pass the table name to a prepared PDO statement?

$stmt = $dbh->prepare('SELECT * FROM :table WHERE 1'); if ($stmt->execute(array(':table' => 'users'))) {     var_dump($stmt->fetchAll()); } 

Is there another safe way to insert a table name into a SQL query? With safe, I mean that I don't want to do

$sql = "SELECT * FROM $table WHERE 1" 
like image 436
Jrgns Avatar asked Oct 08 '08 11:10

Jrgns


People also ask

How does PDO work in PHP?

PDO—PHP Data Objects—are a database access layer providing a uniform method of access to multiple databases. It doesn't account for database-specific syntax, but can allow for the process of switching databases and platforms to be fairly painless, simply by switching the connection string in many instances.

How does PDO prepared statements work?

In layman's terms, PDO prepared statements work like this: Prepare an SQL query with empty values as placeholders with either a question mark or a variable name with a colon preceding it for each value. Bind values or variables to the placeholders. Execute query simultaneously.

Which of the following function is used to execute the query in PDO?

To prepare and execute a single SQL statement that accepts no input parameters, use the PDO::exec or PDO::query method.


2 Answers

Table and Column names CANNOT be replaced by parameters in PDO.

In that case you will simply want to filter and sanitize the data manually. One way to do this is to pass in shorthand parameters to the function that will execute the query dynamically and then use a switch() statement to create a white list of valid values to be used for the table name or column name. That way no user input ever goes directly into the query. So for example:

function buildQuery( $get_var )  {     switch($get_var)     {         case 1:             $tbl = 'users';             break;     }      $sql = "SELECT * FROM $tbl"; } 

By leaving no default case or using a default case that returns an error message you ensure that only values that you want used get used.

like image 112
Noah Goodrich Avatar answered Oct 16 '22 02:10

Noah Goodrich


To understand why binding a table (or column) name doesn't work, you have to understand how the placeholders in prepared statements work: they are not simply substituted in as (suitably escaped) strings, and the resulting SQL executed. Instead, a DBMS asked to "prepare" a statement comes up with a complete query plan for how it would execute that query, including which tables and indexes it would use, which will be the same regardless of how you fill in the placeholders.

The plan for SELECT name FROM my_table WHERE id = :value will be the same whatever you substitute for :value, but the seemingly similar SELECT name FROM :table WHERE id = :value cannot be planned, because the DBMS has no idea what table you're actually going to select from.

This is not something an abstraction library like PDO can or should work around, either, since it would defeat the 2 key purposes of prepared statements: 1) to allow the database to decide in advance how a query will be run, and use the same plan multiple times; and 2) to prevent security issues by separating the logic of the query from the variable input.

like image 45
IMSoP Avatar answered Oct 16 '22 00:10

IMSoP