문제

htmlspecialchars()가 길이가 0인 문자열을 반환하게 만드는 특정 문자열(완전히 인쇄할 수는 없지만 아래에서 볼 수 있음)을 발견했습니다.이 문제를 해결할 수 있는 방법이 있나요?

$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
도움이 되었습니까?

해결책

이제 길이가 0인 문자열을 반환하는 이유를 이해합니다.이런 질문을 해서 죄송합니다.포스팅하기 전에 좀 더 조사했어야 했는데.어쨌든 대답은 다음과 같습니다.

PHP 매뉴얼에서 htmlspecialchars 페이지:

입력 문자열에 지정된 인코딩 내에서 유효하지 않은 코드 단위 시퀀스가 ​​포함된 경우 ENT_IGNORE 또는 ENT_SUBSTITUTE 플래그가 설정되지 않은 한 빈 문자열이 반환됩니다.

그런 다음 이 문자열에서 "잘못된" 것이 무엇인지 스스로에게 묻습니다.위키에서 UTF-8 페이지 UTF-8 인코딩에 대한 좋은 다이어그램을 제공합니다."일반 텍스트 ASCII"를 나타내는 모든 코드 포인트는 0-127입니다(바이트의 MSB는 항상 0입니다).

바이트의 MSB가 1(십진수 128 ~ 255)이면 코드 포인트가 다중 바이트 체인으로 구성되어 있음을 UTF-8 호환 파서에 알립니다. 그리고 다음 바이트의 처음 두 개의 최상위 비트는 1이어야 하고 그 뒤에 0이 와야 합니다.

분명히 이 문자열에서는 한 바이트가 127을 초과하고 다음 바이트가 1 & 0으로 시작하지 않는 경우가 있습니다.따라서 잘못된 UTF-8 인코딩입니다.

에 감사하다 이 SO 게시물 내 의견으로는 ENT_SUBSTITUTE 플래그를 사용하는 것입니다(또는 이러한 부적합 바이트를 삭제해도 문제가 발생하지 않을 것이라고 확신하는 경우 ENT_IGNORE라고 가정합니다). 보안 문제).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top