PHP导出XML文件时数据丢失问题求助
问题:导出XML文件时数据丢失
尝试将数据库数据导出为XML并提供浏览器下载,文件能正常下载但部分数据丢失。数据库连接正常,所有数据可从表中正常获取,此前未接触过PHP XML操作。
相关代码片段:
<?php include('session.php'); if (isset($_POST['exportxml'])) { $filename = 'Data_Backup_' . date('m-d-Y_his') . '.xml'; $domtree = new DOMDocument('1.0', 'UTF-8'); $domtree->formatOutput = true; $xml = new XMLWriter(); header('Content-Disposition: attachment;filename=' . $filename); header('Content-Type: text/xml'); $xml->openURI("php://output"); $xml->setIndent(true); $xml->startElement('data'); if (isset($_POST['exportaccounts'])) { $query = "SELECT * from users"; $result = mysqli_query($conn, $query); if (mysqli_num_rows($result) > 0) { while ($row = mysqli_fetch_assoc($result)) { $xml->startElement("useraccount"); $xml->writeElement("id", $row['id']); $xml->writeElement("username", $row['username']); $xml->writeElement("email", $row['email']); $xml->writeElement("state", $row['state']); $xml->endElement(); } } } if (isset($_POST['exporttimzezone'])) { $query7 = "SELECT * from options where optionname = 'timezone'"; $result7 = mysqli_query($conn, $query7); if (mysqli_num_rows($result7) > 0) { while ($row7 = mysqli_fetch_assoc($result7)) { $xml->startElement("timezone"); $xml->writeElement("id", $row7['id']); $xml->writeElement("optionname", $row7['optionname']); $xml->writeElement("value", $row7['value']); $xml->writeElement("state", $row7['state']); $xml->endElement(); } } } $xml->startElement("version"); $xml->writeElement("id", "1.0"); $xml->endElement(); $xml->endElement(); echo $domtree->saveXML(); exit; $xml->flush(); ?>
问题原因
- 混用XML操作类且逻辑错误:代码同时实例化了
DOMDocument和XMLWriter,但$domtree完全没参与XML内容构建,最后却输出它的空XML结构,干扰了XMLWriter的正常输出。 - 提前终止脚本:
exit写在$xml->flush()之前,XMLWriter的内容还在缓存中未输出就终止脚本,导致数据丢失。 - POST参数拼写错误:
$_POST['exporttimzezone']里的timzezone少了字母e,应为timezone,导致时区数据的导出逻辑永远不会触发。
修复后的代码
<?php include('session.php'); if (isset($_POST['exportxml'])) { $filename = 'Data_Backup_' . date('m-d-Y_his') . '.xml'; // 移除无用的DOMDocument实例 $xml = new XMLWriter(); header('Content-Disposition: attachment;filename=' . $filename); header('Content-Type: text/xml'); $xml->openURI("php://output"); $xml->setIndent(true); $xml->startDocument('1.0', 'UTF-8'); // 初始化XML文档,添加标准声明头 $xml->startElement('data'); if (isset($_POST['exportaccounts'])) { $query = "SELECT * from users"; $result = mysqli_query($conn, $query); if (mysqli_num_rows($result) > 0) { while ($row = mysqli_fetch_assoc($result)) { $xml->startElement("useraccount"); $xml->writeElement("id", $row['id']); $xml->writeElement("username", $row['username']); $xml->writeElement("email", $row['email']); $xml->writeElement("state", $row['state']); $xml->endElement(); } } } // 修正POST参数拼写错误 if (isset($_POST['exporttimezone'])) { $query7 = "SELECT * from options where optionname = 'timezone'"; $result7 = mysqli_query($conn, $query7); if (mysqli_num_rows($result7) > 0) { while ($row7 = mysqli_fetch_assoc($result7)) { $xml->startElement("timezone"); $xml->writeElement("id", $row7['id']); $xml->writeElement("optionname", $row7['optionname']); $xml->writeElement("value", $row7['value']); $xml->writeElement("state", $row7['state']); $xml->endElement(); } } } $xml->startElement("version"); $xml->writeElement("id", "1.0"); $xml->endElement(); $xml->endElement(); // 闭合data元素 $xml->endDocument(); // 闭合XML文档 $xml->flush(); // 输出缓存的XML内容 exit; } ?>
额外说明
- 必须调用
$xml->startDocument()生成标准XML声明头,否则导出的文件不符合XML格式规范。 - 移除无用的
DOMDocument实例,避免资源浪费和逻辑混乱。 - 调整
exit位置,确保所有XML内容输出完成后再终止脚本。
内容的提问来源于stack exchange,提问作者Colin Jack
相关产品推荐
相关产品推荐

