2012-04-04 48 views
1

我有一個類似的類有很多的方法,但是getData()只返回$column參數的值。非常基本的PDO()方法

private $db; 

function __construct() 
{ 
    $this->db = new PDO('sqlite:\db'); 
} 

public function getData($rowid, $column) 
{ 
    $st = $this->db->prepare('SELECT ? FROM tbl WHERE rowid=?'); 
    $st->bindParam(1, $column, PDO::PARAM_STR); 
    $st->bindParam(2, $rowid, PDO::PARAM_INT); 
    if ($st->execute()) 
     return $st->fetchColumn(); 
    else 
     return false; 
} 

類和getData()作品離開了一半的每個其他部分。這裏有什麼問題?

回答

2

bindParam是用來綁定參數,而不是標識符。你有綁定的值將被擴展爲:

SELECT 'some_value' FROM tbl WHERE rowid='some_other_value'; 

...因此等同於:

SELECT 'some_value'; 

,才應使用參數實際參數

$this->db->prepare('SELECT '.$column.' FROM tbl WHERE rowid=?'); 

如果你的列是用戶提供的,你想逃避它,使用正確的轉義函數。在這種情況下,它的SQLite3::escapeString()

$column = SQLite3::escapeString($column); 
$this->db->prepare('SELECT '.$column.' FROM tbl WHERE rowid=?'); 

如果列不是用戶提供的,你真的沒有逃避它。

+1

要添加:如果列是用戶提供的,代碼可能會聞到。 – erenon 2012-04-04 17:36:35

+0

@erenon:可能,但不一定。在使用情況下,提供列名的用戶比維護代碼中的列列表更好的設計選擇。這很少見,但可能會發生。雖然好點。 – netcoder 2012-04-04 17:40:07

0

標識符不是字符串。
您無法綁定標識符。
您必須將其列入白名單。

或 - 更好 - 設計,將不需要動態字段名的所有應用程序正確方法。

+0

假設'$ column'是用戶提供的,這可能不是這種情況。沒有辦法用實際的代碼來說明。 – netcoder 2012-04-04 17:44:03

+0

假設設計不好。 – 2012-04-04 17:47:42

+0

@netcoder它不是。這個類應該是PDO和應用程序邏輯之間的某種更具體的接口。只有'$ rowid'是用戶提供的,我正確地轉義它。 – 2012-04-04 17:51:09