萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP XML 處理實戰:DOM、SimpleXML、XMLReader 與 XML-RPC 整合

PHP XML 三大解析模型

模型特性適用場景記憶體
DOM (Document Object Model)樹狀結構完整載入記憶體,支援完整 CRUD、XPath、XSLT中小型 XML、需修改結構、XSLT 轉換高 (整份文件)
SimpleXML物件導向 API,屬性/子元素如屬性存取,支援 XPath讀取導向、結構固定、開發效率優先高 (整份文件)
XMLReader (Pull Parser)流式讀取,游標前進,不載入整份文件大型 XML (GB 級)、記憶體受限、單向讀取極低 (串流)

DOMDocument 完整範例

<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <book id="bk101">
    <title>XML Developer's Guide</title>
    <author>Gambardella, Matthew</author>
    <price>44.95</price>
  </book>
</catalog>
XML;

$dom = new DOMDocument();
$dom->loadXML($xml);
$dom->formatOutput = true; // 美化輸出

// XPath 查詢
$xpath = new DOMXPath($dom);
$books = $xpath->query('//book[@id="bk101"]');
foreach ($books as $book) {
    echo "Title: " . $xpath->evaluate('string(title)', $book) . "\n";
    // 修改
    $price = $xpath->query('price', $book)->item(0);
    $price->textContent = '49.95';
    // 新增屬性
    $book->setAttribute('updated', 'true');
}

echo $dom->saveXML();
// 載入/儲存檔案
// $dom->load('large.xml');
// $dom->save('output.xml');
?>

SimpleXML 範例

<?php
$xml = simplexml_load_string($xmlString); // 或 simplexml_load_file('file.xml')
// 存取如物件屬性
echo $xml->book[0]->title . "\n";
// 迭代
foreach ($xml->book as $book) {
    echo (string)$book->title . ' - ' . (string)$book->price . "\n";
}
// XPath
$results = $xml->xpath('//book[price > 40]');
// 命名空間
$xml->registerXPathNamespace('ns', 'https://example.com/ns');
$nsResults = $xml->xpath('//ns:item');

// 轉 DOM 進行複雜操作
$dom = dom_import_simplexml($xml)->ownerDocument;
?>

XMLReader 大檔案串流處理

<?php
$reader = new XMLReader();
$reader->open('huge.xml'); // 或 XML($string)

while ($reader->read()) {
    if ($reader->nodeType === XMLReader::ELEMENT && $reader->localName === 'book') {
        // 擴展為 SimpleXML 節點處理 (僅該節點樹)
        $node = simplexml_import_dom($reader->expand());
        $id = (string)$node['id'];
        $title = (string)$node->title;
        // 處理單筆...
        if ($id === 'bk101') {
            echo "Found: $title\n";
            break; // 可提前結束
        }
    }
}
$reader->close();
?>

XML 驗證 (DTD / XSD)

<?php
$dom = new DOMDocument();
$dom->load('data.xml');
if (!$dom->schemaValidate('schema.xsd')) {
    foreach (libxml_get_errors() as $error) {
        error_log("XML 驗證錯誤: {$error->message} at line {$error->line}");
    }
    libxml_clear_errors();
}
?>

安全**:防 XXE 攻擊:libxml_disable_entity_loader(true) (PHP 8.0+ 預設關閉外部實體)。

XML-RPC 客戶端/伺服器端 (舊式 Web Service)

注意:現代專案建議改用 REST/JSON 或 gRPC。XML-RPC 僅用於維護舊系統整合。

伺服器端 (xmlrpc 擴展)

<?php
function sample_add($method, $params) {
    return $params[0] + $params[1];
}

$server = xmlrpc_server_create();
xmlrpc_server_register_method($server, 'sample.add', 'sample_add');

$request = file_get_contents('php://input');
$response = xmlrpc_server_call_method($server, $request, null);
header('Content-Type: text/xml');
echo $response;
xmlrpc_server_destroy($server);
?>

客戶端

<?php
$request = xmlrpc_encode_request('sample.add', [5, 3]);
$ctx = stream_context_create(['http' => [
    'method' => 'POST',
    'header' => 'Content-Type: text/xml',
    'content' => $request,
]]);
$response = file_get_contents('https://localhost/xmlrpc_server.php', false, $ctx);
$result = xmlrpc_decode($response);
echo "5 + 3 = $result\n"; // 8
?>

現代替代方案建議

  • REST + JSON:通用、工具鏈豐富、人類可讀、效能佳。
  • GraphQL:客戶端按需查詢、強型別 Schema。
  • gRPC / Protocol Buffers:高效能、強契約、支援多語言、雙向串流。
  • SOAP:企業級標準、WS-Security、WSDL 契約,若對接銀行/ERP 系統仍需支援。

效能優化提示

  • 大檔案**必須**用 XMLReader 或 SAX (xml_parser_create)。
  • 重複查詢同一文件:快取 DOM/SimpleXML 物件或編譯後的 XPath。
  • 生成大型 XML:使用 XMLWriter (流式寫入,低記憶體)。
  • 啟用 OPcache、JIT (PHP 8.0+) 加速 XML 解析內部函數。
copyright © 萬盛學電腦網 all rights reserved