PHP Conference Japan 2024

DOMDocument::save

(PHP 5, PHP 7, PHP 8)

DOMDocument::save 將內部 XML 樹狀結構傾印回檔案

說明

public DOMDocument::save(字串 $filename, 整數 $options = 0): 整數|false

從 DOM 表示法建立 XML 文件。此函數通常在從頭建立新的 dom 文件後調用,如下例所示。

參數

filename

已儲存 XML 文件的路徑。

options

其他選項。目前僅支援 LIBXML_NOEMPTYTAG

回傳值

返回寫入的位元組數,如果發生錯誤則返回 false

範例

範例 #1 將 DOM 樹儲存到檔案中

<?php

$doc
= new DOMDocument('1.0');
// 我們想要一個漂亮的輸出
$doc->formatOutput = true;

$root = $doc->createElement('book');
$root = $doc->appendChild($root);

$title = $doc->createElement('title');
$title = $root->appendChild($title);

$text = $doc->createTextNode('This is the title');
$text = $title->appendChild($text);

echo
'Wrote: ' . $doc->save("/tmp/test.xml") . ' bytes'; // 寫入:72 位元組

?>

另請參閱

新增註釋

使用者貢獻的註釋 5 則註釋

chenel324 at gmail dot com
16 年前
我花了很長時間才發現
DOMDocument->formatOutput = true
只會對從磁碟載入的文件產生影響,如果同時設定
DOMDocument->preserveWhiteSpace = false ....

希望這可以幫其他人省點麻煩。
siegparr at NOSPAM dot web dot de
18 年前
即使您設定了 XML 的字元編碼(例如,作為 DOMDocument 建構函式的第二個參數),XML 解析器也會將 XML 文件的文字轉換為 UTF-8。使用 load() 命令解析 XML 後,其所有文字都已轉換為 UTF-8。

如果您要將包含特殊字元(例如變音符號)的文字節點附加到 XML 文件中,則應事先使用 utf8_encode() 將文字轉換為 UTF-8,然後再將文字附加到文件中。否則,您會在 save() 命令執行時收到類似「由於轉換錯誤,輸出轉換失敗」的錯誤訊息。請參閱以下範例

<?php
// 要插入下方 XML 的文字
$txt = "包含特殊字元(例如 'ä'、'ß'、'Ü' 等)的文字";

// 建立 DOMDocument 的實例
$dom = new DOMDocument;
// 載入 XML 檔案
// 先前使用 DOMDocument('1.0', 'iso-8859-1') 建立
$dom = $dom->load("file.xml");
// 尋找父節點
$parent = $dom->documentElement;
// 建立 DomXPath 的實例
$xpath = new DomXPath($dom);
// 新節點將插入此節點之前
$next = $xpath->query("//parentnode/childnode");
// 建立新元素
$new_elem = $dom->createElement('new_elem');
// 插入新元素
$parent->insertBefore($new_elem, $next->item(0));
// DOMXML = utf-8! (僅在 'save()' 時才會轉換為 iso-8859-1)
// 防止在 'save()' 時出現「由於轉換錯誤,輸出轉換失敗」的錯誤訊息
$txt = utf8_encode($txt);
// 使用 utf-8 編碼的字串建立新的文字節點
$nodetext = $dom->createTextNode("$txt");
// 將文字節點附加到新元素
$nodetext = $new_elem->appendChild($nodetext);
// 儲存
$dom->save("file.xml");
?>

希望這對某些人有所幫助。

siegparr
dubois-holvoet dot patrick at neuf dot fr
8 年前
我只是想針對 DOMDocument::save() 函式搭配 PHP serialize() 函式的使用提供一些小小的心得。

有時您可能需要先將 PHP 物件序列化,再將其放入 XML 結構(或其他結構)中。然後,我猜您可能需要將此 XML 結構儲存到檔案中。當然,您之後需要讀取此檔案並將其反序列化才能使用其內容。

當要序列化的物件中有一些屬性被宣告為 Protected 時,就會出現問題。

正如 PHP 文件中所述,serialize 函式會在這些 protected 屬性的名稱前後加上星號,並在星號的兩側加上 NULL 字元。
在這種情況下,DOMDocument::save() 函式會在遇到要儲存的字串中的第一個 NULL 字元之前停止儲存操作,因為 PHP 將其視為潛在風險。
因此,之後就無法對檔案進行反序列化操作。

為了解決這個問題,以下是第一種解決方案:

對於序列化,在 DOMDocument::save() 之前:
`$data_serial = explode("\x00\x2A\x00", serialize($object));` //移除 'NULL * NULL' 字串
`$data_serial = implode("\x5C\x30\x2A\x5C\x30", $data_serial);` //並以 '\0*\0' 字串取代

在反序列化之前:
`$data_serial = explode("\x5C\x30\x2A\x5C\x30", $serialized_object);` //移除 '\0*\0' 字串
`$serial_object = implode("\x00\x2A\x00", $data_serial);` //並以先前的序列化所包含的 'NULL * NULL' 字串取代

以及第二種解決方案:

對於序列化,在 DOMDocument::save() 之前:
`$serialized_object = addslashes(serialize($object));`

在應用程式中重新使用物件之前:
`$object = unserialize(stripslashes($serialized_object));`

希望這對一些人有所幫助。
ludvig at ergopedia dot no
10 年前
從頭開始建立 DOMDocument 並儲存時,編碼將會是 utf-8,即使它被宣告為 iso-8859-1。

載入宣告並儲存為 iso-8859-1 的 XML 檔案時,PHP 在修改後儲存時會保留正確的編碼。

PHP 會在內部將宣告為 iso-8859-1 的檔案轉換為 utf-8。要新增包含特殊字元的文字,文字必須編碼為 utf-8。儲存文件時,特殊字元會轉換為 iso-8859-1。

要儲存從頭開始建立的 xml,請使用 fopen/fwrite 和 utf8_decode

`$doc = new DOMDocument('1.0', 'iso-8859-1');`

//使用適當的方法新增一些節點和文字

`$f = fopen('xmlfile.xml', 'w+');`
`fwrite($f, utf8_decode($doc->saveXML()));`
`fclose($f);`
john at johnreid dot it
11 年前
當我因為檔案權限而無法儲存已編輯的 XML 檔案時,即使我知道檔案權限沒問題,我也一直碰壁。

最終,我意識到由於某些奇怪的原因,當我去儲存 XML 檔案時,它會嘗試將檔案寫入根目錄。

因此,在載入 XML 檔案時,請使用 realpath() 保留完整的系統路徑。

<?php
$myfile
= 'myxml.xml';
$myfile = realpath($myfile);
$doc = new DOMDocument('1.0');
$doc->load($myfile);

// 為了示範,我們新增幾個元素
$root = $doc->documentElement;

$title = $doc->createElement('title');
$title = $root->appendChild($title);

$text = $doc->createTextNode('This is a title');
$text = $title->appendChild($text);

$doc->save($myfile);
?>
To Top