PHP에서 XML 파일을 처리하는 것은 일반적인 작업이며 XML_PARSE ()는 이러한 데이터를 처리하는 일반적인 기능입니다. 그러나 수십 개의 메가 바이트 또는 수백 메가 바이트와 같은 슈퍼 큰 XML 파일에 직면하면 성능 병목 현상이 노출됩니다. 이 기사는 XML_PARSE () 의 원칙과 초대형 XML 파일을 처리 할 때 최적화하기위한 몇 가지 전략을 심층적으로 탐색합니다.
XML_PARSE () 함수는 이벤트 기반 XML 파서 (예 : 국외)에 의존합니다. 중소형 XML 파일에서 잘 작동하지만 큰 XML 파일로 작업 할 때 다음과 같은 문제가 발생할 수 있습니다.
거대한 메모리 소비
속도가 느립니다
높은 CPU 사용
I/O를 차단하면 시스템 응답이 느려집니다
대부분의 문제는 다음과 같은 점에 기인 할 수 있습니다.
전체 XML 파일을 한 번에 읽으면 메모리 압력이 생성됩니다.
처리 로직은 너무 중앙 집중화되거나 동기화되어 스트리밍을 최대한 활용합니다.
콜백 함수는 부적절하게 처리되어 성능 낭비가됩니다.
파서 자원은 청소 또는 재사용되지 않았습니다.
전체 XML 파일을 한 번에로드하는 대신 Fopen 과 Fread를 사용하여 청크의 XML 컨텐츠를 읽고 한 번에 컨텐츠의 작은 부분을 파서에 공급하는 것이 좋습니다.
$parser = xml_parser_create();
xml_set_element_handler($parser, "startElement", "endElement");
xml_set_character_data_handler($parser, "characterData");
$fp = fopen("https://m66.net/files/large-xml-file.xml", "r");
if (!$fp) {
die("열 수 없습니다 XML 문서");
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($parser, $data, feof($fp))) {
die(sprintf("XML 실수: %s 그 과정에서 %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
}
}
xml_parser_free($parser);
fclose($fp);
이것의 장점은 메모리 풋 프린트가 항상 제어 가능하며 파일이 크더라도 모든 컨텐츠를 한 번에로드하지는 않는다는 것입니다.
등록 된 콜백 함수의 실행 효율은 전체 구문 분석 속도에 직접 영향을 미칩니다. 콜백에서 데이터베이스 및 디스크와 같은 복잡한 논리 또는 빈번한 느린 I/O 작업을 피하십시오.
function startElement($parser, $name, $attrs) {
// 단순화 된 논리,추가 판단이나 둥지를 피하십시오
if ($name === "ITEM") {
// 필요한 데이터 필드 만 기록하십시오
global $currentItem;
$currentItem = [];
}
}
function characterData($parser, $data) {
global $currentItem;
$data = trim($data);
if (!empty($data)) {
$currentItem[] = $data;
}
}
function endElement($parser, $name) {
global $currentItem;
if ($name === "ITEM") {
// 처리 또는 캐시 저장 결과 지연
// saveToDatabase($currentItem); // 비동기식 또는 배치 처리가 더 좋습니다
// 샘플 처리 코드:
file_put_contents("/tmp/parsed-items.log", json_encode($currentItem) . "\n", FILE_APPEND);
}
}
XML_PARSE () 를 지속적으로 사용하면 여지없는 메모리 문제가 발생할 수 있습니다. XML_PARSER_FREE ()를 사용하여 파서를 제거하고 필요한 경우 전역 변수를 지우십시오.
XML_PARSE는 이벤트 중심 구문 분석에 적합하지만 PHP의 XMLReader는 보다 현대적인 방법을 제공하고 스트리밍 읽기를 지원하며보다 제어 가능합니다.
$reader = new XMLReader();
$reader->open("https://m66.net/files/large-xml-file.xml");
while ($reader->read()) {
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == "item") {
$node = $reader->readOuterXML();
// 거래하십시오 item 마디
}
}
$reader->close();
최적화 효과를 정량화하려면 다음과 같은 테스트 방법을 사용하는 것이 좋습니다.
메모리와 시간 소비를 기록하려면 memory_get_usage () 및 microtime () 을 사용하십시오.
Strace 또는 Xdebug 로 시스템 호출 및 병목 현상을 추적합니다
일회성 로딩과 청킹 처리 간의 자원 점유의 차이 비교
슈퍼 큰 XML 파일을 처리 할 때 XML_PARSE ()를 최적화하는 키는 " 제어 자원 사용 + 간소화 처리 로직 "입니다. 청크 독서 및 얇은 콜백 사용의 우선 순위를 정한 다음 XMLREADER와 같은보다 강력한 구문 분석 도구를 필요에 따라 사용하는 것이 좋습니다.
권장 조합 :
일반적인 작업 : xml_parse () + fread () + 콜백 단순화
대규모 데이터 분석 : XMLREADER + 지연 처리 + 배치 저장
합리적인 최적화를 통해 수백 MB의 XML 파일에 직면해도 효율적이고 안정적인 구문 분석 프로세스를 달성 할 수 있습니다.
관련 태그:
xml_parse