PHP 內建基於 Expat 庫的 XML 擴展,提供事件驅動(SAX 風格)解析器,適合處理大型 XML 文件而不佔用大量記憶體。Apache 1.3.7+ 環境無需額外庫,編譯 PHP 時加入 --with-xml 即可啟用。
| 函式 | 用途 |
|---|---|
xml_parser_create() | 建立解析器資源 |
xml_set_element_handler() | 設定開始/結束標籤回呼 |
xml_set_character_data_handler() | 設定文字內容回呼 |
xml_parse() | 逐塊解析 XML 資料 |
xml_parser_free() | 釋放解析器資源 |
xml_get_error_code() | 取得錯誤代碼 |
xml_error_string() | 錯誤代碼轉可讀訊息 |
<?php
$url = 'https://example.com/feed.xml';
$xml = file_get_contents($url);
$parser = xml_parser_create();
$items = [];
$current = '';
$currentItem = [];
xml_set_element_handler($parser,
function ($p, $name, $attrs) use (&$current, &$currentItem, &$items) {
$current = $name;
if ($name === 'ITEM') $currentItem = [];
},
function ($p, $name) use (&$current, &$currentItem, &$items) {
if ($name === 'ITEM' && $currentItem) {
$items[] = $currentItem;
}
$current = '';
}
);
xml_set_character_data_handler($parser,
function ($p, $data) use (&$current, &$currentItem) {
if ($current && isset($currentItem[$current])) {
$currentItem[$current] .= $data;
} elseif ($current) {
$currentItem[$current] = $data;
}
}
);
if (!xml_parse($parser, $xml, true)) {
die(sprintf("XML Error: %s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)
));
}
xml_parser_free($parser);
print_r($items);
xml_set_element_handler($parser,
function ($p, $name, $attrs) {
// $attrs 為關聯陣列:['attr_name' => 'value', ...]
// 命名空間前綴包含在 $name 中,如 'dc:creator'
},
...
);
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| Expat (SAX) | 記憶體效率高、串流處理 | 程式碼較繁瑣、需自行管理狀態 | 大型 XML、記憶體受限、高效能需求 |
| DOMDocument | 完整樹狀結構、支援 XPath、可修改 | 載入整份文件到記憶體 | 中小型 XML、需隨機存取、轉換輸出 |
| SimpleXML | 語法簡潔、屬性/子元素如物件屬性存取 | 大檔案記憶體壓力大、命名空間處理較弱 | 快速原型、設定檔、API 回應解析 |
$xml = simplexml_load_file('feed.xml');
$xml->registerXPathNamespace('dc', 'https://purl.org/dc/elements/1.1/');
foreach ($xml->xpath('//item') as $item) {
echo (string)$item->title . "\n";
echo (string)$item->xpath('dc:creator')[0] . "\n";
}
expand() 可在需要時將特定節點轉為 SimpleXML/DOM 節點,兼顧效能與便利性。libxml_disable_entity_loader(true) 防止 XXE 攻擊。PHP 的 XML 支援已相當成熟。選擇 Expat/SAX 處理大型串流資料,SimpleXML/DOM 處理一般應用,XMLReader 兼顧兩者。配合命名空間、XPath、Schema 驗證,可構建健壯的資料交換與整合方案。