2011-11-08 133 views
0

我在保持MySQL查詢直線時非常糟糕,但除此之外,我有一個查詢可用於某些數據輸入,但不是全部。我的猜測是引號在應該出現的位置被轉義。轉義MySQL查詢問題

我有整個查詢字符串在同一時間被轉義。這是不好的做法還是它真的很重要?

這裏的查詢:

"INSERT INTO bio_manager_pubs(userid,category,citation,date,link,requests) VALUES (".  
$userid.",'". 
$_POST['category']."', '". 
htmlentities($_POST['pub'])."', 
FROM_UNIXTIME(".strtotime($_POST['date'])."),'". 
$_POST['link']."', 
0)" 

查詢:

  • 用戶名和請求是整數
  • 鏈接和類別的小文本(不知道這是適當的,但最多爲255字符,那麼VarChar會更好?)
  • 日期是一個日期(是否更好重新格式化與PHP或重新格式化與MySQL?)
  • 引用是文本字段

任何想法?

感謝

編輯: 回答這個問題被張貼四次有abouts其中,問題是我逃避整個查詢。

什麼是遺漏的,並造成一些混淆的代碼圍繞查詢。 正是這樣

$db->query($query) 

這其中函數查詢是:

public function query($SQL) 
{ 
    $this->SQL = $this->mysqli->real_escape_string($SQL); 
    $this->result = $this->mysqli->query($SQL); 

    if ($this->result == true) 
    { 
     return true; 
    } 
    else 
    { 
     printf("<b>Problem with SQL:</b> %s\n", $this->SQL); 
     exit; 
    } 
} 

我只是發現了一類使人生小項目簡單,堅持了下來一點。現在,我遇到的問題是刪除$this->mysqli->real_escape_string($SQL);並在代碼中的其他地方添加轉義。

+0

你可以給出具體的案例,它的工作原理和失敗的地方?我看到你用mysql-real-escape-string標記了你的問題,但是根本沒有看到你使用它,它可能只是你的問題的答案。 – lanzz

+0

您是否嘗試過'echo'或'var_dump'這個字符串,看看它是什麼樣子?請花點時間熟悉這一點:http://en.wikipedia.org/wiki/SQL_injection – Quasdunk

+0

建議使用mysql_error()記錄失敗的查詢,並嘗試插入數據並從中找出原因模式和錯誤消息.... – optimusprime619

回答

1

我真的沒有看到任何對$ _POST數據進行消毒,並且在插入數據庫之前確實沒有必要運行htmlentities,當您將該數據顯示在頁面上時應該這樣做。確保清理您的帖子!使用mysql_real_escape_string()或最好使用PDO和預準備語句。

如果您在整個查詢中運行mysql_real_escape_string(),那麼在構建它之後,就會發生這種情況。

在單個帖子上使用它,和/或轉換應該只能是整數數字的變量。

繼承人什麼,我會在你的情況下,將其更改爲:

$posted = $_POST; 

foreach($posted as &$value) 
    $value = mysql_real_escape_string($value); 

$date = strtotime($posted['date']); 


$q = "INSERT INTO bio_manager_pubs(userid,category,citation,date,link,requests) VALUES 
(
'{$userid}', 
'{$posted['category']}', 
'{$posted['pub'])}', 
FROM_UNIXTIME({$posted['date']}), 
'{$posted['link']}', 
'0' 
)"; 
0

我認爲你需要用你的每一個投入在mysql_real_escape_string,而不是整個查詢(只有一次!)。除此之外,它看起來對我很好。

"INSERT INTO bio_manager_pubs(userid,category,citation,date,link,requests) VALUES (".  
mysql_real_escape_string($userid).",'". 
mysql_real_escape_string($_POST['category'])."', '". 
mysql_real_escape_string(htmlentities($_POST['pub']))."', 
FROM_UNIXTIME(".mysql_real_escape_string(strtotime($_POST['date']))."),'". 
mysql_real_escape_string($_POST['link'])."', 
0)" 
1

我認爲構建整個查詢然後逃避整個事情被認爲是不好的做法。輸入代碼後應立即清理輸入,而不是在開始使用它們來建立數據庫交互之後。

你想要消毒每個輸入,有點像這樣:

$category = mysql_real_escape_string($_POST['category']) 

然後你會使用局部變量,而不是投入,建立自己的SQL指令(S)。

此外,您可能希望查看諸如PDO之類的數據訪問,它爲您管理了許多詳細信息。

+0

感謝您的PDO鏈接,我從未真正聽說過他們。我目前使用的類似乎是在試圖做這樣的事情(但不是很完整)。 –

0

而是逃離整個SQL查詢(可以運行摔東西的風險),只是逃避用戶的輸入:

$userid = mysql_real_escape_string($userid); 
$cat = mysql_real_escape_string($_POST['category']); 
$pub = mysql_real_escape_string($_POST['pub']); 
$date = strtotime($_POST['date']); 
$link = mysql_real_escape_string($_POST['link']); 
$query = "INSERT INTO bio_manager_pubs(userid, category, citation, date, link, requests)" 
          ." VALUES ($userid, '$cat', '$pub',  $date, '$link', 0  );"; 
0

那麼一開始你應該避免直接在使用外部數據源的數據查詢,所以我會重寫代碼,以免在查詢中使用$ _POST。更好的是,如果你可以使用PDO或類似的來逃避你的數據。在將數據插入數據庫之前,我會避免使用htmlentities來轉換文本。將數據從數據庫中提取出來之後,您最好做到這一點,因爲您可以在其他(非HTML)輸出上下文中使用該數據。

但是就內聯代碼而言,你有magic_quotes嗎?

嘗試是這樣的

if (get_magic_quotes_gpc()) { 
    $category = stripslashes($_POST['category']); 
    $pub = stripslashes($_POST['pub']); 
    $link = stripslashes($_POST['link']); 
} else { 
    $category = $_POST['category']; 
    $category = $_POST['category']; 
    $category = $_POST['category']; 
} 
$category = mysql_escape_string($category); 
$pub = mysql_escape_string($pub); 
$link = mysql_escape_string($link); 
$sql = " 
    INSERT INTO bio_manager_pubs(userid,category,citation,date,link,requests) VALUES (  
    ". $userid.", 
    '$category', 
    '$pub', 
    FROM_UNIXTIME(".strtotime($_POST['date'])."), 
    '$link', 
    0 
)"; 
0

關閉magic_quotes_gpc的,用準備好的語句。

如果禁用了magic_quotes_gpc,那麼最終不會自動轉義輸入 - 而magic_quotes_gpc也不推薦使用。

使用參數綁定準備語句來避免SQL注入而不是轉義字符。我個人建議使用PDO或MDB2與您的數據庫交談,但您也可以使用mysqli驅動程序執行準備好的語句。請注意,mysql驅動程序也位於砧板上,因此您不久將被迫使用mysqli或MDB2等抽象層。

我敢打賭,magic_quotes_gpc是你的問題。