2011-08-23 95 views
0

檢查下面的方法。如果在文本框中輸入的值是\ mysql_real_escape_string將返回雙反斜線,但preg_replace將只返回帶有一個反斜槓的SQL。我對正則表達式不太好,所以請幫忙。preg_replace&mysql_real_escape_string問題清除SQL

$sql = "INSERT INTO tbl SET val='?'"; 
$params = array('someval'); 

public function execute($sql, array $params){ 
    $keys = array(); 

    foreach ($params as $key => $value) { 
     $keys[] = '/[?]/'; 
     if (get_magic_quotes_gpc()) { 
      $value = stripslashes($value); 
     } 
     $paramsEscaped[$key] = mysql_real_escape_string(trim($value)); 
    } 

    $sql = preg_replace($keys, $paramsEscaped, $sql, 1, $count); 
    return $this->query($sql); 

} 
+0

爲什麼使用preg_replace修改SQL查詢後,您已編碼的值?並看看PDO,它支持準備好的聲明,以防萬一你想模擬它。 – hakre

+0

要替換?與值 –

+0

我已經在下面添加了一個答案,preg_replace不是真的適合這個。它顯示了一個演示爲什麼不,以及一些代碼如何做到這一點。如果你有興趣使你的軟件工作,你應該仔細閱讀一份清單。 – hakre

回答

1

對我來說,它基本上看起來像你重新發明輪子,你的概念有一些嚴重的缺陷:

  • 它假定get_magic_quotes_gpc可以接通。此功能已損壞。你不應該對它進行編碼。而是讓你的應用程序要求關閉它。
  • mysql_real_escape_string需要數據庫鏈接標識符才能正常工作。你沒有提供任何。這是一個嚴重的問題,你應該改變你的概念。
  • 你實際上並沒有使用準備好的語句,但是你模仿了那些語法。這是愚弄其他開發人員,他們可能認爲在不使用代碼的情況下使用代碼是安全的。這是非常不鼓勵的。

但是讓我們來做,但是不要使用preg_replace作爲工作。這是由於各種原因,但尤其是,因爲?的第一個模式導致用第一個參數替換所有內容。處理諸如太少或太多參數/佔位符的錯誤情況是不靈活的。另外設想一個你插入的字符串也包含一個?字符。它會打破它。相反,已經處理的零件以及替換件需要被跳過(Demo of such)。

對於您需要穿過去,把它拆開,並對其進行處理:

public function execute($sql, array $params) 
{ 
    $params = array_map(array($this, 'filter_value'), $params); 

    $sql = $this->expand_placeholders($sql, $params); 

    return $this->query($sql); 
} 

public function filter_value($value) 
{ 
    if (get_magic_quotes_gpc()) 
    { 
     $value = stripslashes($value); 
    } 
    $value = trim($value); 
    $value = mysql_real_escape_string($value); 
    return $value; 
} 

public function expand_placeholders($sql, array $params) 
{ 
    $sql = (string) $sql; 
    $params = array_values($params); 
    $offset = 0; 
    foreach($params as $param) 
    { 
     $place = strpos($sql, '?', $offset); 
     if ($place === false) 
     { 
      throw new InvalidArgumentException('Parameter/Placeholder count mismatch. Not enough placeholders for all parameters.'); 
     } 
     $sql = substr_replace($sql, $param, $place, 1); 
     $offset = $place + strlen($param); 
    } 
    $place = strpos($sql, '?', $offset); 
    if ($place === false) 
    { 
     throw new InvalidArgumentException('Parameter/Placeholder count mismatch. Too many placeholders.'); 
    } 
    return $sql; 
} 

與已有準備好的語句的好處是,他們實際工作。你應該考慮使用這些。對於玩這樣的遊戲很不錯,但最終你需要處理更多的案例,並且重新使用由其他數千用戶測試的現有組件要容易得多。

+0

是的,它,謝謝。我寧願使用mysqli,但這是一個遺留代碼,應用程序是從2003年開始的,所以我只能在這一點上擴展。 –