PHP의 XML 파서 (일반적으로 XML_PARSER_CREATE () 및 XML_PARSE ( )과 같은 국외 거주 기반 함수를 사용하는 경우 여러 XML 데이터 블록을 구문 분석하기 위해 프로그램에서 XML_PARSE ()를 여러 번 호출합니다. 각 구문 분석 전에 파서를 제대로 재설정하거나 재현하지 않으면 일련의 예상치 못한 문제가 발생할 수 있습니다. 이러한 문제의 이유와 피해야하는 방법을 자세히 분석해 봅시다.
XML 파서는 현재 구문 분석중인 노드의 깊이, 구문 분석 된 컨텐츠 버퍼 등과 같이 내부적으로 상태를 유지합니다. 동일한 파서 인스턴스를 사용하여 동일한 파서 인스턴스를 사용하여 여러 XML 문서를 재설정하거나 파괴하지 않고 이전 문서가 다음 문서의 구문 분석에 영향을 줄 수 있습니다.
예:
$xml1 = "<note><to>John</to></note>";
$xml2 = "<message><from>Jane</from></message>";
$parser = xml_parser_create();
// 첫 번째 분석
xml_parse($parser, $xml1);
// 두 번째 파서가 사용됩니다
xml_parse($parser, $xml2); // 구문 분석 오류가 발생할 수 있습니다!
xml_parser_free($parser);
위의 코드에서 XML2 데이터를 두 번째로 구문 분석 할 때 $ Parser는 여전히 첫 번째 구문 분석 XML1 의 상태 정보를 유지하며, 이는 구문 오류, 논리적 판단 예외 및 직접 실패로 이어질 수 있습니다.
PHP의 XML 파서는 xml_set_element_handler ()를 통해 시작 및 엔드 요소에 대한 콜백 함수를 설정할 수 있습니다. 이러한 콜백은 일반적으로 특정 외부 변수 또는 상태에 의존합니다. 컨텍스트 또는 상태 변수가 여러 구문 분석간에 제대로 청소되지 않으면 데이터 혼동을 쉽게 만듭니다.
예:
function startElement($parser, $name, $attrs) {
echo "태그 시작: $name\n";
}
function endElement($parser, $name) {
echo "엔드 태그: $name\n";
}
$parser = xml_parser_create();
xml_set_element_handler($parser, "startElement", "endElement");
$xml = "<user><name>시험</name></user>";
xml_parse($parser, $xml);
// 그런 다음 다른 문서를 구문 분석합니다
$xml2 = "<product><title>상품</title></product>";
xml_parse($parser, $xml2); // 콜백은 부적절하게 처리 될 수 있습니다
$ parser가 재설정되지 않기 때문에 콜백 또는 일부 내부 상태의 바인딩이 비정상적 일 수있어 논리 처리가 혼란 스러울 수 있습니다.
다른 인코딩을 사용하기 전후의 두 XML 문서 (예를 들어, 하나는 UTF-8이고 다른 하나는 ISO-8859-1 인 경우) 그러나 구문자는 여전히 이전 설정을 사용하고 재구성되지 않은 경우, 차량화 또는 구문 분석 실패를 유발할 수도 있습니다.
$parser = xml_parser_create("UTF-8");
$xml1 = "<?xml version='1.0' encoding='UTF-8'?><data>안녕하세요</data>";
$xml2 = "<?xml version='1.0' encoding='ISO-8859-1'?><data>Olá</data>";
xml_parse($parser, $xml1);
xml_parse($parser, $xml2); // 코딩 충돌,오류 가보고 될 수 있습니다
위의 문제를 피하기 위해 모범 사례는 새 XML 문서가 구문 분석하고 파싱 후 리소스를 확보 할 때마다 새 파서 인스턴스를 작성하는 것입니다.
function parseXml($xmlString) {
$parser = xml_parser_create("UTF-8");
xml_parse($parser, $xmlString, true);
xml_parser_free($parser);
}
$xml1 = "<note><to>John</to></note>";
$xml2 = "<message><from>Jane</from></message>";
parseXml($xml1);
parseXml($xml2);
이것은 상태 간섭, 일관성이없는 인코딩 및 콜백 혼동과 같은 문제를 피합니다.
여러 XML 데이터를 처리 할 때 구문 분석기를 "깨끗하게"유지하는 것이 중요합니다. 파서를 직접 재사용하면 자원을 절약 할 수 있지만, 그 결과 상태 오염, 코딩 충돌 및 기타 문제는 종종 노력의 가치가 없습니다. 가장 안전한 방법은 "한 번 사용하고 한 번 구축 한 후 구문 분석 한 후 파괴하는 것"입니다.
예를 들어 XML 데이터를 자주 처리하는 데 필요한 인터페이스를 개발하는 경우 다음과 같습니다.