2012-07-29 124 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)。