2012-07-29 104 views
1

我遇到了一個特殊的字符串(它不是完全可打印的,但你可以在下面看到它),導致htmlspecialchars()返回一個零長度的字符串。有什麼辦法可以解決這個問題嗎?htmlspecialchars導致文本消失

$Stmnt = 'SELECT subject_name FROM bans WHERE id = 2321'; 
$Fetch = $Conn->query($Stmnt); 
if(!$Fetch) 
    die('Could not query DB'); 
while($Row = $Fetch->fetch_array(MYSQLI_ASSOC)) 
{ 
    $RawName = $Row['subject_name']; 
    $RawLen = strlen($RawName); 
    echo('RAW NAME: ['.$RawName.']'.', LENGTH: ['.$RawLen.']'.'<br />'); 
    for($i = 0; $i < $RawLen; $i++) 
     echo('CHAR '.$i.' = ['.$RawName[$i].'] (ORD: '.ord($RawName[$i]).')<br />'); 

    $CleanName = htmlspecialchars($RawName, ENT_QUOTES, 'UTF-8'); 
    $CleanLen = strlen($CleanName); 
    echo('CLEAN NAME: ['.$CleanName.']'.', LENGTH: ['.$CleanLen.']'.'<br />'); 
    for($i = 0; $i < $CleanLen; $i++) 
     echo('CHAR '.$i.' = ['.$CleanName[$i].'] (ORD: '.ord($CleanName[$i]).')<br />'); 
} 
$Fetch->close(); 
echo('DONE'); 

輸出:

RAW NAME: [━═★ Coммander Fι5н �], LENGTH: [31] 
CHAR 0 = [�] (ORD: 226) 
CHAR 1 = [�] (ORD: 148) 
CHAR 2 = [�] (ORD: 129) 
CHAR 3 = [�] (ORD: 226) 
CHAR 4 = [�] (ORD: 149) 
CHAR 5 = [�] (ORD: 144) 
CHAR 6 = [�] (ORD: 226) 
CHAR 7 = [�] (ORD: 152) 
CHAR 8 = [�] (ORD: 133) 
CHAR 9 = [ ] (ORD: 32) 
CHAR 10 = [C] (ORD: 67) 
CHAR 11 = [o] (ORD: 111) 
CHAR 12 = [�] (ORD: 208) 
CHAR 13 = [�] (ORD: 188) 
CHAR 14 = [�] (ORD: 208) 
CHAR 15 = [�] (ORD: 188) 
CHAR 16 = [a] (ORD: 97) 
CHAR 17 = [n] (ORD: 110) 
CHAR 18 = [d] (ORD: 100) 
CHAR 19 = [e] (ORD: 101) 
CHAR 20 = [r] (ORD: 114) 
CHAR 21 = [ ] (ORD: 32) 
CHAR 22 = [F] (ORD: 70) 
CHAR 23 = [�] (ORD: 206) 
CHAR 24 = [�] (ORD: 185) 
CHAR 25 = [5] (ORD: 53) 
CHAR 26 = [�] (ORD: 208) 
CHAR 27 = [�] (ORD: 189) 
CHAR 28 = [ ] (ORD: 32) 
CHAR 29 = [�] (ORD: 226) 
CHAR 30 = [�] (ORD: 148) 
CLEAN NAME: [], LENGTH: [0] 
DONE 

回答

7

我現在明白爲什麼它返回一個零長度字符串。對不起,問這個問題。在發佈之前,我應該研究更多。無論如何,答案如下:

在PHP手冊page for htmlspecialchars

如果輸入字符串包含內的無效代碼單元序列中的給定的編碼一個空字符串將被返回,除非是ENT_IGNORE或ENT_SUBSTITUTE標誌被設置。

然後我問自己什麼是對這個字符串「無效」?在Wiki page for UTF-8上,它給出了UTF-8編碼的一個很好的圖。代表「純文本ASCII」的所有代碼點將爲0-127(該字節中的MSB始終爲0)。

如果一個字節的MSB是1(十進制的128到255),它會告訴符合UTF-8的分析器,該代碼點由多字節鏈組成。 下一個字節的頭兩個最高有效位必須是1後面是0

顯然,在這種字符串中,存在一個字節是在127和後面的字節沒有開始的情況下,與1 & 0.因此它是無效的UTF-8編碼。

感謝this SO post的分辨率,這在我看來,是使用ENT_SUBSTITUTE標誌(或我想ENT_IGNORE如果你確信刪除這些不符合規定的字節不會a security issue)。