PHP Conference Japan 2024

DOMDocument::save

(PHP 5, PHP 7, PHP 8)

DOMDocument::save 将内部 XML 树转储回文件

描述

public DOMDocument::save(string $filename, int $options = 0): int|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'; // Wrote: 72 bytes

?>

参见

添加注释

用户贡献的注释 5 条注释

chenel324 at gmail dot com
16 年前
我花了很长时间才发现
DOMDocument->formatOutput = true
只有在也设置了以下内容时,才能对从磁盘加载的文档产生影响:
DOMDocument->preserveWhiteSpace = false ....

希望这能帮其他人避免头痛。
siegparr at NOSPAM dot web dot de
18 年前
XML 解析器会将 XML 文档的文本转换为 UTF-8,即使您已设置 XML 的字符编码(例如,作为 DOMDocument 构造函数的第二个参数)。使用 load() 命令解析 XML 后,其所有文本都已转换为 UTF-8。

如果您将带有特殊字符(例如变音符号)的文本节点附加到 XML 文档,则应在将文本附加到文档之前,使用 utf8_encode() 将其转换为 UTF-8。否则,在 save() 命令处会收到类似“由于转换错误导致输出转换失败”的错误消息。请参见下面的示例

<?php
// 要插入到下面 XML 的文本
$txt = "a text with special characters like 'ä', 'ß', 'Ü' etc.";

// 创建 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 结构保存到文件中。当然,您还需要进一步读取此文件并在使用其内容之前对其进行反序列化。

当要序列化的对象中存在一些被声明为受保护的属性时,问题就会出现。

正如 PHP 文档中所写,serialize 函数会在这些受保护属性的名称前添加一个星号,并在星号的两侧各添加一个 NULL 字符。
在这种情况下,由于PHP认为空字符(NULL)存在潜在风险,`DOMDocument::save` 函数会在遇到第一个空字符时停止保存操作。
因此,之后文件的反序列化操作将变得不可能。

为了解决这个问题,这里提供第一个解决方案:

对于序列化,在 `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 并保存时,即使声明为 iso-8859-1,编码也将为 utf-8。

加载声明并保存为 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()` 来保留 XML 文件的完整系统路径

<?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