문자열을 "XML 안전"으로 만드는 방법은 무엇입니까?
PHP 에코를 통해 XML 문서를 보내 AJAX 호출에 응답하고 있습니다. 이 XML 문서를 구성하기 위해 데이터베이스 레코드를 반복합니다. 문제는 데이터베이스에 '<'기호가있는 레코드가 포함되어 있다는 것입니다. 따라서 당연히 브라우저는 특정 지점에서 오류를 발생시킵니다. 이 문제를 어떻게 해결할 수 있습니까?
를 사용하여 해당 문자를 이스케이프 htmlspecialchars
하거나 더 적절하게 DOMDocument 또는 XMLWriter 와 같은 XML 문서를 빌드하기위한 라이브러리를 사용합니다 .
또 다른 대안은 CDATA 섹션을 사용하는 것이지만 ]]>
.
또한 XML 문서에 대해 정의한 인코딩 (기본적으로 UTF-8)을 준수해야한다는 점도 고려하십시오.
PHP 5.4부터 다음을 사용할 수 있습니다.
htmlspecialchars($string, ENT_XML1);
다음과 같은 인코딩을 지정해야합니다.
htmlspecialchars($string, ENT_XML1, 'UTF-8');
최신 정보
위의 경우에만 변환됩니다.
&
...에&
<
...에<
>
...에>
큰 따옴표로 묶인 속성에서 사용하기 위해 텍스트를 이스케이프하려면 다음을 수행하십시오.
htmlspecialchars($string, ENT_XML1 | ENT_COMPAT, 'UTF-8');
변환됩니다 "
에 "
뿐만 아니라 &
, <
하고 >
.
속성이 작은 따옴표로 묶인 경우 :
htmlspecialchars($string, ENT_XML1 | ENT_QUOTES, 'UTF-8');
변환됩니다 '
에 '
추가하여 &
, <
, >
와 "
.
(물론 속성 외부에서도 사용할 수 있습니다.)
htmlspecialchars에 대한 수동 항목을 참조하십시오 .
1) 다음과 같이 텍스트를 CDATA로 래핑 할 수 있습니다.
<mytag>
<![CDATA[Your text goes here. Btw: 5<6 and 6>5]]>
</mytag>
참조 http://www.w3schools.com/xml/xml_cdata.asp를
2) 이미 누군가가 말했듯이 : 그 문자를 이스케이프하십시오. 예 :
5<6 and 6>5
이 시도:
$str = htmlentities($str,ENT_QUOTES,'UTF-8');
따라서 htmlentities()
함수를 사용하여 데이터를 필터링 한 후 다음 과 같은 XML 태그의 데이터를 사용할 수 있습니다.
<mytag>$str</mytag>
가능하다면 항상 문자열 조작보다는 XML 클래스를 사용하여 XML을 생성하는 것이 좋습니다. 클래스가 필요에 따라 자동으로 문자를 이스케이프한다는 이점 중 하나입니다.
누군가를 돕는 경우에 이것을 추가하십시오.
일본어 문자로 작업하면서 인코딩도 적절하게 설정되었습니다. 그러나 때때로, 나는 그것을 발견 htmlentities
하고 htmlspecialchars
충분하지 않다.
일부 사용자 입력에는 위의 기능으로 제거되지 않은 특수 문자가 포함되어 있습니다. 이 경우 다음을 수행해야합니다.
preg_replace('/[\x00-\x1f]/','',htmlspecialchars($string))
이것은 또한 또는 xml-unsafe
같은 특정 제어 문자를 제거 합니다. 이 표 를 사용 하여 생략 할 문자를 결정할 수 있습니다 .Null character
EOT
나는 Golang이 XML에 대해 인용 이스케이프하는 방식을 선호합니다 (그리고 줄 바꿈 이스케이프 및 다른 문자 이스케이프와 같은 몇 가지 추가 기능), 따라서 XML 이스케이프 기능을 아래 PHP로 포팅했습니다.
function isInCharacterRange(int $r): bool {
return $r == 0x09 ||
$r == 0x0A ||
$r == 0x0D ||
$r >= 0x20 && $r <= 0xDF77 ||
$r >= 0xE000 && $r <= 0xFFFD ||
$r >= 0x10000 && $r <= 0x10FFFF;
}
function xml(string $s, bool $escapeNewline = true): string {
$w = '';
$Last = 0;
$l = strlen($s);
$i = 0;
while ($i < $l) {
$r = mb_substr(substr($s, $i), 0, 1);
$Width = strlen($r);
$i += $Width;
switch ($r) {
case '"':
$esc = '"';
break;
case "'":
$esc = ''';
break;
case '&':
$esc = '&';
break;
case '<':
$esc = '<';
break;
case '>':
$esc = '>';
break;
case "\t":
$esc = '	';
break;
case "\n":
if (!$escapeNewline) {
continue 2;
}
$esc = '
';
break;
case "\r":
$esc = '
';
break;
default:
if (!isInCharacterRange(mb_ord($r)) || (mb_ord($r) === 0xFFFD && $Width === 1)) {
$esc = "\u{FFFD}";
break;
}
continue 2;
}
$w .= substr($s, $Last, $i - $Last - $Width) . $esc;
$Last = $i;
}
$w .= substr($s, $Last);
return $w;
}
mb_ord
사용법 때문에 최소한 PHP7.2가 필요 하거나 다른 폴리 필로 교체해야하지만이 함수는 우리에게 잘 작동합니다!
궁금한 사람을 위해 관련 Go 소스 https://golang.org/src/encoding/xml/xml.go?s=44219:44263#L1887
참고 URL : https://stackoverflow.com/questions/3426090/how-do-you-make-strings-xml-safe
'Programing' 카테고리의 다른 글
모든 관계를 포함하여 Eloquent 객체를 복제 하시겠습니까? (0) | 2020.12.07 |
---|---|
JavaScript onClick 이벤트 핸들러에서 큰 따옴표 이스케이프 (0) | 2020.12.07 |
자바 스크립트 배열에서 요소를 제거하는 깨끗한 방법 (jQuery, coffeescript 사용) (0) | 2020.12.07 |
CPU가 SSE3 명령 세트를 지원하는지 확인하는 방법은 무엇입니까? (0) | 2020.12.07 |
피보나치 재귀 함수는 어떻게 "작동"합니까? (0) | 2020.12.07 |