2013-09-30 88 views
1

我有一個小問題越來越與PDO準備一個SQL查詢,我有這樣的代碼:PHP PDO自定義的SQL查詢準備

$portfolio = $db->prepare("SELECT * FROM `news`, `:sub` WHERE `news`.`id` = `:sub`.`id_news` AND `page` = `:under` ORDER BY `date` DESC LIMIT :start, :limit"); 
$portfolio->bindParam(':under', $_GET['under'], PDO::PARAM_STR); 
$portfolio->bindParam(':sub', $_GET['sub'], PDO::PARAM_STR); 
$portfolio->bindParam(':start', $start, PDO::PARAM_INT); 
$portfolio->bindParam(':limit', $limit, PDO::PARAM_INT); 
$portfolio->execute(); 

但是,這並沒有給任何價值,我的數據庫有值正確,任何人都知道爲什麼這不起作用? PS:VAR $開始和$限制都很好,與它沒有任何問題因爲真的是分頁的腳本,在所有頁面做工非常精細。

對於爲例我在網址:mysite.com/index.php?sub=vid &下=信息

所以查詢應該是這樣的:

"SELECT * FROM `news`, `vid` WHERE `news`.`id` = `vid`.`id_news` AND `page` = `info` ORDER BY `date` DESC LIMIT 0, 10" 

那麼什麼我明白以前的代碼應該工作,仍然是安全的嗎?

switch($_GET['sub']){ 
    case "vid": 
     $table = "vid"; 
     break; 
    case "img": 
     $table = "img"; 
     break; 
} 
$portfolio = $db->prepare("SELECT * FROM `news`, `$table` WHERE `news`.`id` = `$table`.`id_news` AND `page` = :under ORDER BY `date` DESC LIMIT :start, :limit"); 
+0

爲什麼你有一個**動態鏈接表?**你的設計有一些可怕的東西,你知道。 –

+0

不能綁定PDO表名;檢查http://stackoverflow.com/questions/182287/can-php-pdo-statements-accept-the-table-name-as-parameter – newfurniturey

+0

這是不可能有動態表名稱,你需要去一個不同的這些動態的方式(但正如你上面所說的那樣,最好查看你的數據庫結構,爲什麼你首先需要這樣做。) –

回答

2

您不能對錶名或列名使用查詢參數佔位符。

使用查詢參數只以替代在表達一個文字值。即帶引號的字符串,帶引號的日期或數字值。

另外,即使您使用字符串或日期的參數,該參數也不會放在引號內。

爲了使表名或列名的動態,你必須應用程序變量插值到您的SQL字符串您提交的字符串準備()。

但是要小心來驗證用戶輸入(例如$ _GET變量),以避免SQL注入。例如,根據已知合法表名稱的列表測試輸入。

例子:

$subtables = array(
"DEFAULT" => "text", 
"text" => "text", 
"vid" => "vid", 
"pic" => "pic" 
); 

// if the key exists, use the table name, else use the default table name 
$subtable = $subtables[ $_GET["sub"] ] ?: $subtables[ "DEFAULT" ]; 

// now $subtable is effectively whitelisted, and it is safe to use 
// without risk of SQL injection 

$portfolio = $db->prepare("SELECT * 
    FROM news, `$subtable` AS sub 
    WHERE news.id = sub.id_news 
    AND page = :under 
    ORDER BY date DESC LIMIT :start, :limit"); 
+0

比爾你能否檢查我的最終代碼是否應該工作並且仍然安全? –

+0

是的,您已將表名列入了白名單。但是你仍然在引號內有':under'參數,這是行不通的。我不知道你是否打算'信息'是一個列名或字符串文字。 –

+0

是的,一切正常,非常感謝您的幫助。 –

-2
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 

兩個神奇的線條您解決最大的一個後,將解決所有的小問題 - 一個動態鏈接表。

什麼它必須是一個表,其中「亞健康」是一個字段名稱,以區分類別

SELECT * FROM news n, subnews s 
WHERE n.id = id_news AND s.sub =:sub AND `page` = :under 
ORDER BY `date` DESC LIMIT :start, :limit 

你也必須退出包裝在反引號一切移動這種習慣。