當前位置: 首頁> 最新文章列表> 通過xml_parse 結合fopen 讀取大文件進行解析的示例

通過xml_parse 結合fopen 讀取大文件進行解析的示例

M66 2025-05-13

在處理XML 文件時,如果文件非常大(例如幾百MB 甚至幾個GB),一次性將整個文件加載到內存中是不現實的。此時,我們可以使用PHP 的xml_parse函數配合fopen和流式讀取的方式,實現邊讀取邊解析,從而節省內存。

下面是一個使用xml_parsefopen解析大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);
?>

說明:

  1. fopen + fread :使用fopen打開遠程或本地文件, fread每次讀取4096 字節,避免內存佔用過高。

  2. xml_parser_create :創建一個XML 解析器資源。

  3. xml_set_element_handler :註冊開始和結束標籤的處理函數。

  4. xml_set_character_data_handler :註冊字符數據的處理函數。

  5. xml_parse :對讀取到的XML 數據塊進行解析,支持多次調用,適合流式處理。

使用場景:

  • 大型數據交換的XML 文件

  • 網絡爬蟲抓取到的結構化XML 數據

  • 日誌系統或配置系統基於XML 的批量分析