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

Il codice sopra riportato funziona correttamente. Tuttavia ho bisogno di inserire un'altra variabile nella dichiarazione preparativa. Ho provato quanto segue ma non sembra funzionare:PHP PDO + Prepare Statement

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

so $ _POST [ 'linguaggio'] (da stampandolo) contiene solo la parola 'inglese'. È possibile inserire una variabile di preparazione in questa parte di una selezione?

thx

+0

Non sembra alcun errore di sintassi, quale codice di errore hai ricevuto? – LotusH

+0

nessun errore - ma piuttosto recuperare il valore dal DB mi dà solo la parola inglese. Questo è il valore nella variabile e nel titolo della colonna nel DB ... – Adam

+0

es .: {"free": "inglese", "meetingles": "inglese", "searchprofiles": "inglese"} ma dovrebbe avere valori diversi in cui la parola inglese è ... – Adam

risposta

7

parametri di query possono prendere il posto di un solo un valore costante - non è un nome di colonna.

Tutte le colonne e le tabelle devono essere denominate nel momento in cui è preparare una query, non è possibile posticipare la scelta delle colonne per il successivo passaggio di esecuzione.

Quando si desidera che l'input dell'utente determini il nome di una colonna, utilizzare una mappa di lista per la whitelist per limitare l'input dell'utente a scelte valide. Le chiavi dell'array della mappa sono gli input dell'utente legale. I valori dell'array della mappa sono le stringhe che si desidera utilizzare nella query SQL, in questo caso i nomi delle colonne.

$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'])); 

In questo modo si può essere sicuri che solo i valori nel $ lang_col_map possono diventare parte della query SQL, e se l'utente tenta di inviare qualcosa di ingannevole nella richiesta HTTP, è ignorata perché non corrisponde qualsiasi chiave di quella mappa. Quindi la query è sicura dall'iniezione SQL.

Vedere la mia presentazione SQL Injection Myths and Fallacies per ulteriori informazioni.

+0

Per impostazione predefinita, tutte le domande/domande devono essere conosciute prima che vengano poste. – Xeoncross

2

Supporto di istruzioni preparate solo i parametri che sono valori supportati dal database.

Nella tua seconda affermazione, il primo "?" è un segnaposto per un nome di colonna, non un valore.

È necessario utilizzare invece un'istruzione SQL dinamica. Per questo, è necessario impedire l'iniezione 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'])); 
}