| 方案 | 記憶體 | 效能 | 易用性 | 適合場景 |
|---|---|---|---|---|
| 字串拼接 | 低(小資料) | 快(小資料) | 簡單但易錯 | 極小、固定結構、一次性輸出 |
| DOMDocument | 高(全樹載入) | 中 | 功能完整、W3C 標準 | 需操作既有 XML、XPath 查詢、XSLT 轉換 |
| XMLWriter | 極低(串流) | 最快 | API 直觀、單向寫入 | 大型 XML、記憶體敏感、高效能輸出 |
| SimpleXML | 中 | 中 | 最簡潔、物件導向 | 中小型 XML、讀取/修改、快速原型 |
<?php
$data = [
['title' => 'title1', 'content' => 'content1', 'pubdate' => '2009-10-11'],
['title' => 'title2', 'content' => 'content2', 'pubdate' => '2009-11-11'],
];
$attr = ['title' => ['size' => 1]];
<?php
function buildXmlString(array $data, array $attr): string
{
$xml = '' . "\n";
$xml .= '' . "\n";
foreach ($data as $item) {
$xml .= ' - ' . "\n";
foreach ($item as $key => $val) {
$xml .= ' <' . $key . '>';
// 關鍵:內容需跳脫 XML 特殊字元
$xml .= htmlspecialchars($val, ENT_QUOTES | ENT_XML1, 'UTF-8');
$xml .= '' . $key . '>' . "\n";
// 屬性處理
if (isset($attr[$key])) {
foreach ($attr[$key] as $aKey => $aVal) {
// 字串拼接處理屬性較繁瑣,這裡略過示範
}
}
}
$xml .= '
' . "\n";
}
$xml .= ' ';
return $xml;
}
echo buildXmlString($data, $attr);
⚠️ 風險: 手動跳脫易漏(`&` `<` `>` `"` `'`),結構錯誤難除錯,不建議生產環境複雜 XML。
<?php
function buildXmlDom(array $data, array $attr): string
{
$dom = new DOMDocument('1.0', 'utf-8');
$dom->formatOutput = true; // 縮排美化
$article = $dom->createElement('article');
$dom->appendChild($article);
foreach ($data as $itemData) {
$item = $dom->createElement('item');
$article->appendChild($item);
foreach ($itemData as $key => $val) {
$elem = $dom->createElement($key);
$item->appendChild($elem);
// createTextNode 自動處理跳脫
$text = $dom->createTextNode($val);
$elem->appendChild($text);
// 屬性
if (isset($attr[$key])) {
foreach ($attr[$key] as $aKey => $aVal) {
$attrNode = $dom->createAttribute($aKey);
$attrNode->value = $aVal;
$elem->appendChild($attrNode);
}
}
}
}
return $dom->saveXML();
}
echo buildXmlDom($data, $attr);
優點: 符合 W3C DOM 標準、支援 XPath/XSchema/XSLT、可載入既有 XML 操作。
缺點: 全樹載入記憶體,大檔案易 OOM。
<?php
function buildXmlWriter(array $data, array $attr): string
{
$writer = new XMLWriter();
$writer->openMemory(); // 或 openUri('php://output') 直接輸出
$writer->setIndent(true);
$writer->setIndentString(' ');
$writer->startDocument('1.0', 'utf-8');
$writer->startElement('article');
foreach ($data as $itemData) {
$writer->startElement('item');
foreach ($itemData as $key => $val) {
$writer->startElement($key);
if (isset($attr[$key])) {
foreach ($attr[$key] as $aKey => $aVal) {
$writer->writeAttribute($aKey, $aVal);
}
}
$writer->text($val); // 自動跳脫
$writer->endElement(); // $key
}
$writer->endElement(); // item
}
$writer->endElement(); // article
$writer->endDocument();
return $writer->outputMemory();
}
echo buildXmlWriter($data, $attr);
殺手級特性: openUri('large.xml') 直接寫入檔案,**不佔用 PHP 記憶體**,適合 GB 級 XML 匯出。
<?php
function buildXmlSimple(array $data, array $attr): string
{
// 從字串建立根節點
$xml = simplexml_load_string('');
foreach ($data as $itemData) {
$item = $xml->addChild('item');
foreach ($itemData as $key => $val) {
$node = $item->addChild($key, $val); // 內容自動跳脫
if (isset($attr[$key])) {
foreach ($attr[$key] as $aKey => $aVal) {
$node->addAttribute($aKey, $aVal);
}
}
}
}
return $xml->asXML();
}
echo buildXmlSimple($data, $attr);
注意: SimpleXML 修改既有 XML 結構(如插入節點、移除屬性)較麻煩,適合「建立新 XML」或「單純讀取」。
需要輸出大檔案 (>50MB) 或記憶體受限?
├─ 是 → XMLWriter (openUri 檔案串流)
└─ 否
需要操作既有 XML(XPath、修改、XSLT)?
├─ 是 → DOMDocument
└─ 否
結構簡單、追求開發速度、團隊熟悉物件導向?
├─ 是 → SimpleXML
└─ 否 → XMLWriter (通用最佳平衡)
-
title1
content1
2009-10-11
-
title2
content2
2009-11-11
現代 PHP 專案**首選 XMLWriter**:串流寫入、低記憶體、高效能、API 清晰、支援所有 XML 特性。SimpleXML 適合快速原型與讀取。DOMDocument 留給需 XPath/XSLT 的複雜操作。字串拼接請限制在極簡單、一次性、無維護壓力的腳本中。