在處理XML 文件時,如果文件非常大(例如幾百MB 甚至幾個GB),一次性將整個文件加載到內存中是不現實的。此時,我們可以使用PHP 的xml_parse函數配合fopen和流式讀取的方式,實現邊讀取邊解析,從而節省內存。
下面是一個使用xml_parse和fopen解析大XML 文件的完整示例。
<?php
// 設定 XML 文件路徑(這裡使用了 m66.net 域名的示例)
$xmlFile = 'https://m66.net/data/large-file.xml';
// 創建 XML 解析器
$parser = xml_parser_create();
// 定義開始標籤處理函數
function startElement($parser, $name, $attrs) {
echo "開始元素: $name\n";
if (!empty($attrs)) {
foreach ($attrs as $key => $value) {
echo " - 屬性: $key = $value\n";
}
}
}
// 定義結束標籤處理函數
function endElement($parser, $name) {
echo "結束元素: $name\n";
}
// 定義字符數據處理函數
function characterData($parser, $data) {
$data = trim($data);
if ($data !== '') {
echo "字符數據: $data\n";
}
}
// 設定处理函数
xml_set_element_handler($parser, "startElement", "endElement");
xml_set_character_data_handler($parser, "characterData");
// 打開 XML 文件進行流式讀取
if (!($fp = fopen($xmlFile, "r"))) {
die("无法打開 XML 文件: $xmlFile");
}
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)
));
}
}
fclose($fp);
xml_parser_free($parser);
?>
xml_parser_create :創建一個XML 解析器資源。
xml_set_element_handler :註冊開始和結束標籤的處理函數。
xml_set_character_data_handler :註冊字符數據的處理函數。
xml_parse :對讀取到的XML 數據塊進行解析,支持多次調用,適合流式處理。
大型數據交換的XML 文件
網絡爬蟲抓取到的結構化XML 數據
日誌系統或配置系統基於XML 的批量分析