2011-12-30 31 views
5
$sql='SELECT phrase,english FROM static_site_language WHERE page=?;'; 
$pds=$database->pdo->prepare($sql); $pds->execute(array($_POST['languagepage'])); 

El código anterior funciona bien. Sin embargo, necesito poner otra variable en la declaración de preparación. He intentado lo siguiente pero no parece funcionar:PHP PDO + Preparar declaración

$sql='SELECT phrase,? FROM static_site_language WHERE page=?;'; 
$pds=$database->pdo->prepare($sql); $pds->execute(array($_POST['language'],$_POST['languagepage'])); 

sé $ _POST [ 'lenguaje'] (de imprimirlo) sólo contiene la palabra 'Inglés'. ¿Es posible poner una variable de preparación en esta parte de una selección?

THX

+0

Parece que no hay error en la sintaxis, ¿qué código de error obtuviste? – LotusH

+0

no hay error, pero en lugar de recuperar el valor del DB, solo me da la palabra inglés. Este es el valor en la variable y el título de la columna en el DB ... – Adam

+0

eg: {"free": "english", "meetsingles": "english", "searchprofiles": "english"} pero debería tener valores diferentes donde la palabra inglés es ... – Adam

Respuesta

7

Los parámetros de consulta pueden tomar el lugar de solamente un valor constante - no es un nombre de columna.

Todas las columnas y tablas deben nombrarse en el momento en que prepare una consulta, no puede posponer la elección de columnas para el siguiente paso de ejecución.

Cuando se desea la entrada del usuario para determinar un nombre de columna, utilice un mapa lista blanca para limitar la entrada del usuario a las opciones válidas. Las teclas de la matriz de mapas son las entradas legales del usuario. Los valores de la matriz de mapas son las cadenas que desea utilizar en la consulta SQL, en este caso, los nombres de columna.

$lang_col_map = array(
    "DEFAULT" => "english", 
    "en"  => "english", 
    "es"  => "spanish" 
); 
$lang_col = $lang_col_map[ $_POST["language"] ] ?: $lang_col_map[ "DEFAULT" ]; 

$sql='SELECT phrase,$lang_col FROM static_site_language WHERE page=?;'; 
$pds=$database->pdo->prepare($sql); 
$pds->execute(array($_POST['languagepage'])); 

De esta manera usted puede estar seguro de que sólo los valores de la $ lang_col_map pueden llegar a ser parte de la consulta SQL, y si el usuario intenta enviar nada complicado en la petición HTTP, es ignorado, ya que no coincide cualquier clave de ese mapa Por lo tanto, la consulta está a salvo de la inyección de SQL.

Consulte mi presentación SQL Injection Myths and Fallacies para obtener más información.

+0

Por diseño, todas las preguntas/consultas deben conocerse antes de que se soliciten. – Xeoncross

2

La declaración preparada admite solo parámetros que son valores admitidos por la base de datos.

En su segunda declaración, la primera "?" es un marcador de posición para un nombre de columna, no un valor.

En su lugar, debe usar una instrucción de SQL dinámico. Para esto, debe evitar la inyección de SQL.

$language_authorized = array('english', 'french', 'spanish'); 
$language = $_POST['language']; 
if (in_array($language_authorized, $language)) { 
    $sql='SELECT phrase,'.$language.' FROM static_site_language WHERE page=?;'; 
    $pds = $database->pdo->prepare($sql); 
    $pds->execute(array($_POST['languagepage'])); 
}