¿Pueden las declaraciones PHP PDO aceptar el nombre de la tabla o columna como parámetro?

Resuelto Jrgns asked hace 54 años • 9 respuestas

¿Por qué no puedo pasar el nombre de la tabla a una declaración PDO preparada?

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

¿Existe otra forma segura de insertar un nombre de tabla en una consulta SQL? Con seguro quiero decir que no quiero hacer

$sql = "SELECT * FROM $table WHERE 1"
Jrgns avatar Jan 01 '70 08:01 Jrgns
Aceptado

Los nombres de tablas y columnas NO PUEDEN reemplazarse por parámetros en PDO.

En ese caso, simplemente querrás filtrar y desinfectar los datos manualmente. Una forma de hacer esto es pasar parámetros abreviados a la función que ejecutará la consulta dinámicamente y luego usar una switch()declaración para crear una lista blanca de valores válidos que se usarán para el nombre de la tabla o el nombre de la columna. De esa manera, ninguna entrada del usuario va directamente a la consulta. Así por ejemplo:

function buildQuery( $get_var ) 
{
    switch($get_var)
    {
        case 1:
            $tbl = 'users';
            break;
    }

    $sql = "SELECT * FROM $tbl";
}

Al no dejar ningún caso predeterminado o utilizar un caso predeterminado que devuelva un mensaje de error, se asegura de que solo se utilicen los valores que desea utilizar.

Noah Goodrich avatar Oct 08 '2008 11:10 Noah Goodrich

Para comprender por qué no funciona vincular el nombre de una tabla (o columna), debe comprender cómo funcionan los marcadores de posición en las declaraciones preparadas: no se sustituyen simplemente como cadenas (adecuadamente con escape) y se ejecuta el SQL resultante. En cambio, un DBMS al que se le pide "preparar" una declaración genera un plan de consulta completo sobre cómo ejecutaría esa consulta, incluidas las tablas e índices que usaría, que serán los mismos independientemente de cómo complete los marcadores de posición.

El plan SELECT name FROM my_table WHERE id = :valueserá el mismo para cualquier cosa que sustituya :value, pero lo que parece similar SELECT name FROM :table WHERE id = :valueno se puede planificar, porque el DBMS no tiene idea de qué tabla realmente va a seleccionar.

Esto tampoco es algo que una biblioteca de abstracción como PDO pueda o deba solucionar, ya que frustraría los 2 propósitos clave de las declaraciones preparadas: 1) permitir que la base de datos decida de antemano cómo se ejecutará una consulta y usar la misma planificar varias veces; y 2) evitar problemas de seguridad separando la lógica de la consulta de la entrada variable.

IMSoP avatar Apr 13 '2013 17:04 IMSoP