2013-04-13 81 views
0
$query = "SELECT :option FROM `site`.`fish` WHERE `fishid`=:fishid"; 
    if ($stmt = $connect->prepare($query)){ 
     $stmt->bindValue(':option', $option, PDO::PARAM_INT); 
     $stmt->bindValue(':fishid', $fishid, PDO::PARAM_INT); 
     $stmt->execute(); 
     $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); 
     echo '<pre>', print_r($rows, true), '</pre>'; 
    } 

下返回PDO將值綁定爲INT?

Array 
(
    [0] => Array 
     (
      [id] => id 
     ) 

) 

我想它返回[ID] => 7 它是與我的BindVaulues ......他們在不被識別爲數字?

+0

是你要綁定一個實際的整數值? –

+0

選擇「:選項」的任何理由?你不能只寫'SELECT id FROM ...'嗎? –

+0

你模仿準備? –

回答

2

隨着準備好的陳述,你想要做什麼是不可能的。

您無法將您即將選擇的列作爲參數傳遞給準備好的語句。聲明將評估如下:

SELECT 'id' ... 

什麼會給你一個字符串'id'而不是列的值。

1

這源於對準備好的語句中的佔位符如何工作的常見誤解:它們不是簡單地以字符串替換,並且生成的SQL被執行。相反,DBMS要求「準備」一個語句時,會提供一個完整的查詢計劃來說明它將如何執行該查詢,包括它將使用哪些表和索引,無論您填入佔位符的方式如何,它們都是相同的。

SELECT name FROM my_table WHERE id = :value的計劃可不管你代替:value相同,但表面上類似SELECT name FROM :table WHERE id = :value不能計劃的,因爲DBMS不知道什麼表格你究竟要從中選擇。設置:value字符串'hello'將相當於SELECT 'hello' FROM my_table,只是返回字符串'hello'爲每一行 -

查詢,形式,SELECT :value FROM my_table只能因爲佔位符代表一個字面值,不是列名計劃結果集。

0

列名不是SQL變量(SQL不支持在那個地方有變量),但它只是在PHP中的字符串:

$option = (string) $option; 

switch ($option) 
{ 
    case "id": 
     break; 

    default: 
     throw new InvalidArgumentException(
     sprintf("Invalid identifier: '%s'", $option) 
    ); 
} 


if (false !== strpos($option, "`")) 
{ 
    throw new InvalidArgumentException(
     sprintf("Invalid column name: '%s'", $option) 
    ); 
} 

$query = sprintf("SELECT `%s` FROM `site`.`fish` WHERE `fishid`=:fishid", $option); 

if ($stmt = $conn->prepare($query)) 
{ 
    $stmt->bindValue(':fishid', $fishid, PDO::PARAM_INT); 
    $stmt->execute(); 
    ... 
+0

重要的是,如果你這樣做,你*必須首先檢查'$ option'對已知列的實際列。否則,如果'$ option'設置爲''1; DROP TABLE site.fish; - '' – IMSoP

+0

@IMSoP:如果用於選擇數據的用戶可能丟棄表格,則確實存在安全風險。好點子。 –

+0

'DROP TABLE'只是一個「不好的東西」的簡單例子。顯然,你應該鎖定用戶,但這並不會使SQL注入成爲一個非問題。如果查詢處於開放狀態,即使只讀訪問也可能被利用。 – IMSoP