2013-08-03 96 views
0

我有這個PDO包裝pdo是否逃避語句?

private function cleanup($bind) { 
    if(!is_array($bind)) { 
     if(!empty($bind)) 
      $bind = array($bind); 
     else 
      $bind = array(); 
    } 
    return $bind; 
} 

public function run($sql, $bind="") { 
    $this->sql = trim($sql); 
    $this->bind = $this->cleanup($bind); 
    $this->error = ""; 
    array_push($this->qs, $sql); 

    try { 
     $pdostmt = $this->prepare($this->sql); 
     if($pdostmt->execute($this->bind) !== false) { 
      if(preg_match("/^(" . implode("|", array("select", "describe", "pragma")) . ") /i", $this->sql)) 
       return $pdostmt->fetchAll(PDO::FETCH_ASSOC); 
      elseif(preg_match("/^(" . implode("|", array("delete", "insert", "update")) . ") /i", $this->sql)) 
       return $pdostmt->rowCount(); 
     } 
    } catch (PDOException $e) { 
     $this->error = $e->getMessage(); 
     $this->debug(); 
     return false; 
    } 
} 

我曾與這個沒有問題,因爲我開始使用它一對夫婦幾年前,因爲字符串沒有逃過我現在收到錯誤消息。也許我從來沒有像這樣的場景。

下面是導致該問題

$db->run("SELECT region_id FROM region WHERE name = '$name'"); 

其中$name是霍克斯灣的SQL語句。我的印象是PDO逃脫了字符串,好像我錯了。任何想法如何解決這個問題?

+0

如果您未使用PDO :: prepare,則需要使用PDO :: quote手動轉義字符串。 – DevlshOne

+0

@DevlshOne'$ pdostmt = $ this-> prepare($ this-> sql);'有準備 – slash197

+0

@ slash197您是否至少閱讀過代碼?沒有什麼可以在聲明中準備 –

回答

3

有2點錯誤的假設,導致你對這個問題

  1. 逃逸是一個東西,它使你的查詢正確的。
  2. PDO做這些「逃避」任何「魔術」的方式,知道什麼可以逃脫。

不幸的是,這兩種假設都是錯誤的。

事實上,對於SQL字符串只有轉義。它與PDO無關,準備好陳述,安全等等。一旦你要將字符串文字放入查詢中,它必須有特殊字符轉義。
但是,一旦你不是 - 沒有逃脫將是好事。

關於PDO,您希望它不會「逃跑」,而是要在您的查詢中處理佔位符。這是整個事情的工作原理。 使用佔位符告訴PDO 格式正確的對應值。雖然這種格式不僅涉及逃避,還涉及更多不同的措施。

因此,它必須是這樣的

$db->run("SELECT region_id FROM region WHERE name = :name", array(':name' => $name)); 

這樣PDO會將$ name的字符串,並相應地格式化。

雖然我不確定「清理」功能,如果它正常工作,爲什麼它被使用。

0

默認情況下,如果您使用普通查詢而非預準備語句,PDO不會引用任何內容。但是您可以使用PDO::quote()方法來轉義個別值。查看更多http://www.php.net/manual/en/pdo.quote.php

+0

您不應該使用此功能,而是準備好語句。 –

+0

這不是我的爭論。 –