PHP에서 XML_PARSE () 는 해외 라이브러리를 사용하는 이벤트 중심의 XML 파서 기능입니다. 이 파서는 SAX (XML의 간단한 API) 파서와 유사하게 작동하여 구문 분석 중에 다른 마크 업이 발생할 때 해당 콜백 기능을 트리거합니다.
그러나 XML_PARSE ()는 DTD (문서 유형 정의)의 세부 구조를 자동으로 구문 분석하지는 않지만 DTD에 직면 할 때 콜백을 트리거하므로 적절한 콜백 기능을 설정하여 DTD를 식별하고 처리 할 수 있습니다.
DTD 선언은 XML 문서에서 허용되는 구조 및 요소 유형을 정의합니다. 보안 및 데이터 검증 측면에서 매우 중요합니다. 일부 시나리오에서는 XML을 구문 분석 할 때 포함 된 DTD를 식별하거나 DTD로 XML을 거부 할 수 있습니다 (XXE 공격 방지).
다음은 XML_PARSER_CREATE () 및 XML_PARSE () 를 사용하고 DTD를 캡처하려는 예입니다.
<?php
$xmlString = <<<XML
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "http://m66.net/dtd/note.dtd">
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
XML;
// 만들다 XML 파서
$parser = xml_parser_create();
// 처리 지침을 위해 콜백 기능을 설정하십시오(처리를 위해 DTD 성명서 등)
function handle_processing_instruction($parser, $target, $data) {
echo "처리 명령 대상: $target\n";
echo "프로세스 명령 데이터: $data\n";
}
// 기본 처리 기능을 설정하십시오
function handle_default($parser, $data) {
if (preg_match('/^<!DOCTYPE/i', trim($data))) {
echo "감지 DTD 성명: $data\n";
}
}
// 콜백 함수 바인드
xml_set_processing_instruction_handler($parser, "handle_processing_instruction");
xml_set_default_handler($parser, "handle_default");
// 구문 분석을 시작하십시오
if (!xml_parse($parser, $xmlString, true)) {
die(sprintf(
"XML 실수: %s 에서 %d 좋아요",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)
));
}
// 리소스를 자유롭게합니다
xml_parser_free($parser);
?>
handle_processing_instruction은 <? xml ...?> 및 기타 처리 지침과 같은 처리 지침을 캡처하는 데 사용됩니다.
handle_default는 다른 프로세서가 가로 채지 않은 대부분의 원시 데이터를 캡처하는 데 사용할 수있는보다 기본 프로세서입니다. 여기서 우리는 그것을 사용하여 <! doctype> 선언이 있는지 확인합니다.
preg_match ( '/^<! doctype/i', $ data)를 사용하여 문자열이 DTD 선언인지 여부를 결정하십시오.
XML 파서를 사용하는 경우 XXE (XML 외부 엔티티 주입) 공격을 방지하십시오. XML_PARSE () 자체는 엔티티 확장 구문 분석을 지원하지 않지만 (국외 거주자는 안전합니다) DOM 또는 SimpleXML과 같은 구문 분석기를 사용하는 경우 외부 엔티티 구문 분석을 비활성화하십시오.
libxml_disable_entity_loader(true);
PHP 8.0+에서는 libxml_disable_entity_loader ()가 더 이상 사용되지 않았지만 기본 동작은 이미 비활성화되었습니다.
XML_PARSE () 자체는 DTD의 구조 내용을 구문 분석하지 않지만 기본 프로세서 또는 처리 명령 콜백을 통해 그 존재를 감지 할 수 있습니다.
신뢰할 수없는 소스에서 XML을 처리 할 때는 보안 취약점을 방지하기 위해 DTD 및 엔티티 확장에주의하십시오.
원격 DTD 참조의 모든 URL은 테스트를 위해 사용자 정의 도메인 이름 (예 : M66.NET )으로 대체 할 수 있습니다.
위의 방법을 통해 XML_PARSE ()를 사용하여 더 많은 유연성으로 XML에서 DTD 선언을 감지하고 처리 할 수 있습니다.