在PHP中处理XML数据时,DOMDocument是最常用也最稳定的原生类之一。它把XML文档映射成一棵节点树,开发者可以像操作HTML DOM一样增删改查元素,而不必手动拼接字符串。掌握它的加载与保存方法,是写接口报文、读配置文件、做数据转换的基础。

一、DOMDocument类基础与创建
DOMDocument是PHP DOM扩展提供的核心类,编译PHP时若开启libxml通常就已可用。使用前先实例化,并可根据需要设置版本与编码,这会影响后续保存时自动生成的XML声明头。
下面代码展示了一个最简实例化过程,并设置了XML 1.0版与UTF-8编码。这两个值在调用saveXML时会被写入声明行,若源文件自身带有声明,则以源文件为准,除非手动覆盖。
<?php
// 创建DOMDocument对象,指定版本和编码
$doc = new DOMDocument('1.0', 'UTF-8');
// 设置缩进格式化输出,便于阅读
$doc->formatOutput = true;
// 设置preserveWhiteSpace可保留原有空白,默认false
$doc->preserveWhiteSpace = false;
?>
二、从字符串加载XML
当XML内容已经存在于变量中,比如接口返回的报文,应使用loadXML方法。该方法解析字符串并返回布尔值表示成功与否,解析错误可通过libxml_get_errors获取。
需要注意的是,字符串必须是合规的XML,否则会触发警告。建议在生产环境用libxml_use_internal_errors(true)屏蔽警告,再自行判断。下面示例演示安全加载并读取根节点名。
<?php
$xmlStr = '<?xml version="1.0" encoding="UTF-8"?><book><title>PHP指南</title></book>';
$doc = new DOMDocument();
libxml_use_internal_errors(true);
if ($doc->loadXML($xmlStr)) {
echo '根节点: ' . $doc->documentElement->nodeName;
} else {
foreach (libxml_get_errors() as $e) {
echo '解析错误: ' . $e->message;
}
libxml_clear_errors();
}
?>
三、从文件加载XML
若XML位于磁盘,例如config.xml,则使用load方法。它和loadXML参数相似,但第一个参数是文件路径,支持本地相对或绝对路径,也能加载网络地址(取决于allow_url_fopen)。
文件加载同样可能失败,常见原因是路径不对或文件无读权限。以下代码演示加载本地文件并遍历子节点,展示基础读取方式。
<?php
$path = '/var/www/config.xml';
$doc = new DOMDocument();
if ($doc->load($path)) {
$root = $doc->documentElement;
foreach ($root->childNodes as $node) {
if ($node->nodeType === XML_ELEMENT_NODE) {
echo $node->nodeName . ': ' . $node->textContent . "n";
}
}
} else {
echo '文件加载失败,请检查路径与权限';
}
?>
四、保存XML到字符串
修改或构建完DOM树后,saveXML方法可将其序列化为字符串,不传参时输出整个文档,传入节点则只输出该节点。这种方式适合直接发往浏览器或写进缓存。
和加载对应,saveXML会依据对象属性生成声明。如果创建时未设编码,而源文件是GBK,则可能乱码,因此统一用UTF-8最省心。示例展示生成字符串并输出。
<?php
$doc = new DOMDocument('1.0', 'UTF-8');
$doc->formatOutput = true;
$root = $doc->createElement('user');
$root->appendChild($doc->createElement('name', '张三'));
$doc->appendChild($root);
$output = $doc->saveXML();
header('Content-Type: text/xml; charset=utf-8');
echo $output;
?>
五、保存XML到文件
save方法负责把文档写入文件路径,返回写入字节数或false。目录需有写权限,且PHP进程用户(如www-data)要能创建文件。它不会自动建目录,需提前mkdir。
与saveXML不同,save直接落盘,常用于生成静态配置或导出数据。下面例子在临时目录写文件并校验结果。
<?php
$doc = new DOMDocument('1.0', 'UTF-8');
$doc->formatOutput = true;
$item = $doc->createElement('log');
$item->appendChild($doc->createTextNode('system start'));
$doc->appendChild($item);
$file = '/tmp/export.xml';
$bytes = $doc->save($file);
if ($bytes !== false) {
echo '已写入 ' . $bytes . ' 字节到 ' . $file;
} else {
echo '保存失败,检查目录权限';
}
?>
六、常见编码与格式问题
中文乱码多因声明编码与实际内容不符。DOMDocument内部以UTF-8处理,若源是GBK,加载前应先转码,或加载后用mb_convert_encoding处理节点值。
另一个坑是formatOutput在load后可能失效,因为原文档空白规则已定。此时可新建文档导入节点,或设preserveWhiteSpace=false再另存,才能正常缩进。
| 场景 | 推荐方法 | 注意点 |
|---|---|---|
| 接口报文解析 | loadXML | 屏蔽警告,校验结构 |
| 本地配置读取 | load | 文件路径与权限 |
| 输出到客户端 | saveXML | 设header防乱码 |
| 导出文件 | save | 目录可写 |
七、小结
DOMDocument通过load与loadXML完成XML载入,用save与saveXML实现持久化或输出。明确字符串与文件两种路径差异,处理好UTF-8编码和格式化开关,就能在多数PHP项目中稳妥地完成XML任务。
对于复杂结构,还可配合XPath查询,但加载保存的主干逻辑不变。建议封装一个读写工具类,统一错误处理与编码设置,减少重复代码。
DOMDocumentXML加载XML保存修改时间:2026-08-03 22:33:30