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

上面的代碼運行良好。不過,我需要在準備聲明中加入另一個變量。我曾嘗試以下,但它似乎並沒有工作: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'])); 

我知道$ _ POST [「語言」(從打印出來)只包含單詞「英語」。 是否可以在選擇的這個部分中放置一個準備變量?

thx

+0

似乎在語法上沒有錯誤,您得到了什麼錯誤代碼? – LotusH 2011-12-30 03:04:40

+0

沒有錯誤 - 而是從數據庫中獲取值,它只是給了我單詞english。這是DB中列的變量和標題的值... – Adam 2011-12-30 03:07:24

+0

例如:{「free」:「english」,「meetingles」:「english」,「searchprofiles」:「english」}但它應該有不同的值,其中英語這個詞是... – Adam 2011-12-30 03:07:54

回答

7

查詢參數可以取代只有一個常數值 - 而不是列名稱。

所有的列和表必須在準備查詢時命名,您不能推遲選擇列到後續執行步驟。

當您希望用戶輸入確定列名稱時,請使用白名單映射將用戶輸入限制爲有效選項。地圖數組的鍵是合法的用戶輸入。 map數組的值是您想要在SQL查詢中使用的字符串,在這種情況下是列名稱。

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

這種方式可以確保只有在$ lang_col_map值可以成爲SQL查詢的一部分,如果用戶試圖發送任何HTTP請求棘手,它忽略了,因爲它不匹配該地圖的任何鍵。所以查詢對於SQL注入是安全的。

查看我的介紹SQL Injection Myths and Fallacies瞭解更多信息。

+0

通過設計,所有問題/疑問應該在被問及之前知道。 – Xeoncross 2011-12-30 03:09:08

2

準備語句僅支持數據庫支持的值。

在你的第二個聲明中,第一個「?」是列名的佔位符,而不是值。

您必須改用動態SQL語句。 爲此,您必須防止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'])); 
} 
相關問題