2011-11-27 523 views
7

我閱讀了PDO,並在StackOverFlow上搜索了關於pdo並準備語句。我想知道什麼是好處或使用準備聲明。例如:PHP PDO準備查詢

$sql = 'SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour'; 
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); 
$sth->execute(array(':calories' => 150, ':colour' => 'red')); 
$red = $sth->fetchAll(); 

VS

$sql = "SELECT name, colour, calories FROM fruit WHERE calories < $calories AND colour = $colour"; 
$result = $connection->query($query); 
$row = $result->fetch(PDO::FETCH_ASSOC); 

兩個查詢將返回相同的結果,那麼爲什麼使用做準備,對我來說它看起來會是比較慢,因爲你必須執行額外的步驟。

感謝

+1

你的第二個例子實際上並不工作 - 你沒有用值替換查詢中的參數! –

+0

@FrancisAvila,好吧..你可以**注入**正確的值,但是,是的,默認情況下它不會工作。 –

+0

在OP的早期版本中,'$ calories'只是':calories'。所以是的,我的評論不再適用。 –

回答

12

預處理語句是:

  1. 更安全:PDO或底層數據庫庫將採取逃避綁定變量對你的照顧。如果您始終使用預準備語句,則永遠不會受到SQL注入攻擊。
  2. (有時)更快:許多數據庫將緩存預準備語句的查詢計劃,並通過符號引用準備好的語句,而不是重新傳輸整個查詢文本。如果您只准備一個語句一次,然後重複使用具有不同變量的預準備語句對象,這是最引人注目的。

這兩個,#1是遠,更重要,並使預備報表不可或缺!如果您沒有使用準備好的語句,唯一理智的做法是在軟件中重新實現此功能。 (正如我已經做了好幾次,當我被迫使用mysql驅動程序,不能使用PDO。)

+0

」啊,是的,'小鮑比表',我們稱他爲...「 http://xkcd.com/327/ – Olie

1

準備使用大量的查詢時,速度更快(你已經準備查詢),它是更安全。

你的第二個代碼可能不起作用 - 你在查詢中使用參數,但是你沒有定義它們。

使用查詢()您必須使用quote()手動填充查詢 - 這是更多的工作,並且傾向於使程序員不小心。

+0

我改正了這個問題 – joel

+0

並且在你更新的代碼中,你將證明你爲什麼不能使用query()。現在,只需更改'$ calories',就可以很容易地執行SQ​​L注入。你的prepare()例子就是注入證明。「 –

0

準備和有約束力的參數是爲了防止SQL注入,
是喜歡的行爲發送給數據庫,
而你的第二個查詢有沒有答辯前逃離該變量。

0

其實是有你錯過了第三個選項:

$stmt = $dbh->prepare(' 
    SELECT 
     name, 
     colour, 
     calories 
    FROM fruit 
    WHERE calories < :calories 
    AND colour = :colour 
'); 
$stmt->bindParam(':calories', $calories, PDO::PARAM_INT); 
$stmt->bindParam(':colour', $colour, PDO::PARAM_STR, 64); 
if ($sth->execute()) 
{ 
    $data = $sth->fetchAll(PDO::FETCH_ASSOC); 
} 

也許我失去了一些東西,但設置光標選項似乎有點毫無意義,如果你最終會做fetchAll()