2014-02-15 57 views
-2

我一直在困惑這一段時間,並終於屈服於在這裏尋求幫助。撇號和反斜槓悖論

我有一個用於抓取的preg_match腳本,它匹配循環中的不同變量並將它們存儲在數組中,最終被髮布到SQL表中。每當變量包含撇號時都會出現問題。

下面是如何抓取和整理數據現在

for($i = 0; $i < count($bokse[0]); $i++){ 
    preg_match_all("/title=\"Mere information om (.+?)\"/sim", $bokse[0][$i], $name, PREG_SET_ORDER); 
    $laeger[$i]['navn'] = stripslashes(mysql_real_escape_string($name[0][1])); 
} 

的東西,我抓住,mysql_escaped價值和剝離可以是:

**Michael D'Angelo** [NOTICE THE APOSTROPHE] 

如果我想回應這給頁,我可以成功地回顯D'angelo正確(帶撇號)

echo $laeger[$i]['navn']; 

會給我Michael D'Angelo。但是,當把它存儲在數據庫中時,我遇到了一個悖論;我可以選擇將其存儲爲Michael D\'Angelo

或者存儲D並接收到SQL錯誤。

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'angelo' 
(..........blablabv...............) 

下面是如何存儲數據

mysql_query("INSERT INTO table (name) VALUES ('".$laeger[$i]['navn']."'")"); or die(mysql_error()); 

取決於如果我的stripslashes與否,我會要麼亂了查詢或陷入困境的結果(用bachflash)。 FML。

+1

'stripslashes'撤銷了什麼'mysql_real_escape_string'做了什麼。這就是爲什麼輸出未被轉義並且稍後不適合SQL字符串上下文的原因。 – mario

+1

我不認爲你明白什麼是悖論。 –

回答

1

正如您在評論中提到的,接受的答案對您沒有任何幫助。它只會在你事先知道你要刮的數據時才起作用,所以你可以把反斜槓放在正確的位置,但是當然你事先不知道,所以你需要一個能在運行時工作的解決方案。 MySQL爲你提供了這樣的解決方案。

可以解決你的問題的答案是您的插入更改爲:

mysql_query("INSERT INTO table (name) VALUES ('".mysql_real_escape_string($laeger[$i]['navn'])."'")"); 

或者像我喜歡做它,即使它是非標準:

mysql_query("INSERT INTO table set name='".mysql_real_escape_string($laeger[$i]['navn'])."'"); 

我認爲,編碼更容易,閱讀也更容易。對於我自己的工作,我創建了一個名爲「dbstring」的「幫助函數」,該函數圍繞轉義函數封裝了撇號,這使得每個數據庫之間的一切變得更加緊湊,更具可讀性,可移植性和SQL注入攻擊抵抗力。

+0

或者可能是一個參數化查詢? – chrylis

5

沒有矛盾。你只是不理解如何逃避作品。

如果您有:

INSERT INTO sometable (fieldname) VALUES ('Michael D\'Angelo') 

反斜槓將獲得進入數據庫的磁盤存儲。它由數據庫的SQL解析器剝離。同樣,當您從表中檢索名稱時,它不會被轉義。你會得到Michael D'Angelo返回給你的客戶。

您擁有的是一個SQL注入攻擊漏洞 - 允許包含SQL元字符的原始用戶提供的數據出現在SQL上下文中,而不會考慮這些元字符。

這就是爲什麼有(如老派代碼)的東西,如mysql_real_escape_string(),它逃脫所提供的字符串中的所有SQL元字符,所以它們變成明文,不再是「元」。

+0

因此,最合理的解決方案是什麼?我對轉義無法轉化爲迴應有點困惑。 – Denmark90

+1

對待逃脫像包裝禮物。包裹阻止了禮物到達收件人之前被「看到」。一旦完成,它就被解開並使用。包裝被用戶扔掉。所以'邁克爾D'安傑洛'是「包裝」的數據庫。它在實際的數據文件中解開並存儲「Michael D'Angelo」。一旦'''實際存儲在數據庫中,它就不能再「中斷」查詢語句,因爲數據庫知道它是字符串的一部分,而不是sql元字符。 –