2010-01-14 18 views
-3

我正在使用mysqli。PHP當一個字符串是雙倍時會發生什麼mysqli_real_escape_string

當我回聲mysqli_real_escape_string($db,mysqli_real_escape_string($db,'"'));

其中那些之一將是輸出: 1. \" 2. \\\"

有沒有安全的方法來檢查字符串是否已經逃脫?

不幸的是,我目前無法測試,因爲我無法24小時訪問MySQL。

+1

刪除了基本上等於「Q:你可以自己測試一下嗎?」,「A:不,我有時間限制,請參閱問題的頂部」的評論。 – 2010-01-14 16:53:19

+4

*嘆*一個完美的問題,它的核心,最後由一個壞句子毀了。不想妄想:如果簡單說明你爲什麼不能自己做而不是做那種sn remark的評論,那會是一個這樣的問題嗎?我們不想要你的生活故事,而是一個簡單的「我現在沒有辦法訪問MySQL」,這個問題會得到它應得的,因爲雙轉義可以很容易地發生,這取決於如何該應用程序的設計... – 2010-01-14 19:05:10

+2

@邁克爾:雖然我同意他可以說,爲什麼換句話說,我不認爲這個問題值得-10票,並被關閉爲「公然攻擊」。 **請**,請讓我「你不能自己動手嗎?」種類的評論。 **謝謝** - 他最後一句話中兩個非常愉快的話。那有多冒犯?我相信我們都需要放鬆一點。投票重新開放。 – 2010-01-14 22:21:45

回答

7

輸出是\\\"(您的第二個示例)。

我不認爲你可以可靠地說出一個字符串是否已經被轉義,你應該組織你的代碼,只能調用mysqli_real_escape_string()一次。

2

生成的字符串將是\\\"(轉義每個字符)。

如果按照「安全」,你的意思是「萬無一失」,那麼沒有。即使您檢查相關字符是否被轉義,您也無法知道假設\",並且字符串不會提供任何可以設置爲將其標記爲已轉義的隱藏標誌。

但是,您不應該手動調用mysqli_real_escape_string兩次。只有在你需要的時刻才能做到。

「雙轉義」的主要來源是當你通過轉義做正確的事情,但是既不關閉魔術引號,也不關閉魔術引號。

*好的,儘可能地接近不用參數化查詢。

3

您無法判斷一個字符串是否已經被轉義,因爲已被轉義的字符串也可能已經被輸入了一個用戶(因此未被轉義)。

+0

,它們沒有任何意義。輸入的'\''與escape_string(''')有什麼不同? – Gal 2010-01-14 16:11:25

+2

這正是我想說的。因爲字符串沒有區別,所以你不能說出哪一個被轉義了。 – CodeAddict 2010-01-14 17:29:30

1

第二個將被退回。 "將首先轉換爲\"(轉義"),然後將轉換爲\\\"(轉義\")。

一般來說,你必須自己做。雖然這確實增加反斜槓字符'"\並在您輸入的數據NULL字符的「功能」 Magic Quotes,魔術引號是一個可怕的發明,將在PHP 6中移除Futhermore他們可以在一個啓用服務器並在另一個上禁用。所以它甚至不可靠。

但更重要的是,他們是不適合MySQL作爲MySQL中,你不僅要採取的唯一其他字符,但這些元字符護理過(見string syntax in MySQL瞭解更多信息)。

0

添加一些額外的信息。

逃逸是額外信息添加到碼元的序列,而不會引入額外的符號的方式。爲了做到這一點,至少一個符號是充當了「逃離」的象徵。這意味着原始角色丟失,需要使用轉義序列添加。

實施例:

我們有3個符號的語言:一個,b和c。其中符號具有以下功能:

Language 1 
a has the function A 
b has the function B 
c has the function C 

現在我們需要來介紹這些功能d和E,但我們無法添加額外的符號。

因此,我們可以使用轉義符做到這一點:

Language 2 
a, is now the escape symbol. 
aa has the function A 
ab had the function D 
ac has the function E 
b has the function B 
c has the function C 

序列aabcabac,如果使用的語言1讀取AABCABAC解釋。但用語言2解釋爲ABCDE。

問題在於,大多數情況下,您無法確定符號中使用的語言。這個元信息需要在數據處理之前提供。

該botom行是你沒有安全的方式來確定一個字符串是否足夠逃脫。

1

多次調用mysqli_real_escape_string()不會使查詢不太安全。但它確實會破壞你的數據。柯南奧布萊恩就是一個很好的例子。

如果你做到以下幾點:

$name=mysqli_real_escape_string($db,mysqli_real_escape_string($db,"Conan O'Brien")); 
//At this point $name is Conan O\\\'Brien 
mysql_query("insert into table (name)values('$name')") 
//In the database the name will be stored as: Conan O\'Brien Which is corrupt. 

爲了應對這種腐敗現象,你可以做到以下幾點:

funciton strip_all($var){ 
    $len=strlen($var); 
    $ret=stripslashes($var); 
    while($len!=strlen($ret)){ 
     $len=strlen($ret); 
     $ret=stripslashes($ret); 
    } 
    return ret; 
} 
//$name is unkown somthing like: Conan O\\\\\\\'Brien 
$name=strip_all($name); 
//$name is: Conan O'Brien 
$name=mysqli_real_escape_string($db,$name); 
//$name is: Conan O\'Brien, which is properly escaped. 
mysql_query("insert into table (name)values('$name')") 
//In the database the value is Conan O'Brien, mysql will eat the back slash. 

,最好的方法是跟蹤您的轉義的來源。在這種情況下,我們說明magic_quotes是否被禁用或啓用,然後我們使用mysqli_real_escape_string(),它提供了更好的安全性,因爲它逃脫了更多的字符。

if(get_magic_quotes_gpc()) 
{ 
    $name=stripslashes($_GET[name]); 
} 
$name=mysqli_real_escape_string($db,$_GET[name]); 
//At this point $name is Conan O\'Brien 
mysql_query("insert into table (name)values('$name')") 
相關問題