我的网站上有一个PHP页面,它基本上是一个简单的接收器,用于报告我的软件。如果用户打开了报告,则会向我的php页面提交一些基本值对,然后将其记录到我服务器上的xml文件中。这似乎工作得非常好,除了有时(相当频繁地)它创建的xml文件在文件末尾看起来是一个截断的额外xml片段,这使得它不是有效的xml。它很容易修复,因为我可以删除截断的部分并且它再次有效,但我不确定它为什么这样做,如果它缺少一些应该存在的数据。
例如,这是最近一个文件的简化版本:
<?xml version="1.0" encoding="UTF-8"?>
<RDSoftwareReports>
<RDSoftwareReport SoftwareType="workFlow">
<ProgramTime Open="9:58:07 AM" Close="4:00:17 PM"/>
<Commands/>
</RDSoftwareReport>
</RDSoftwareReports>
reReport>
</RDSoftwareReports>
你可以看到最后两行看起来像是另一个文件的结尾,并且报告卡在那里。这是经常访问的,所以我不知道这是一个并发或多台机器同时提交报告的问题,但如果有人有任何见解,我将非常感激:)。
这是我的php代码:
<?php
$software = $_POST["swType"];
$rvtVersion = $_POST["rvtVer"];
$id = $_POST["id"];
$version = $_POST["ver"];
$path = $_POST["path"];
$licenseType = $_POST["lType"];
$licenseScope = $_POST["lScope"];
$osVersion = $_POST["osVer"];
$osNumerical = $_POST["osNum"];
$os64 = $_POST["os64"];
$specialVersion = $_POST["spVer"];
$programOpen = $_POST["pOpen"];
$programClose = $_POST["pClose"];
$fileData = $_POST["fData"];
$commandData = $_POST["cmds"];
$reportDate = date("m/d/Y");
//Get the report path, one per day
$reportPath = "Reports_".date("m_d_Y").".xml";
//echo $reportPath."<br /><br />";
//Create the file for today if it doesn't exist
if(!file_exists($reportPath))
{
$writer = new XMLWriter();
$writer->openUri($reportPath);
$writer->startDocument('1.0','UTF-8');
$writer->setIndent(4);
$writer->startElement("RDSoftwareReports");
$writer->endElement();
$writer->endDocument();
$writer->flush();
}
//echo $reportPath."<br /><br />";
//Read the xml file in
$xml = simplexml_load_file($reportPath);
$reportNode = $xml->addChild("RDSoftwareReport");
$reportNode->addAttribute("SoftwareType",$software);
$reportNode->addAttribute("RevitVersion",$rvtVersion);
$reportNode->addAttribute("ID",$id);
$reportNode->addAttribute("ReportDate",$reportDate);
$reportNode->addAttribute("Version",$version);
$reportNode->addAttribute("Path",$path);
$reportNode->addAttribute("LicenseType",$licenseType);
$reportNode->addAttribute("LicenseScope",$licenseScope);
$reportNode->addAttribute("OSVersion",$osVersion);
$reportNode->addAttribute("NumVersion",$osNumerical);
$reportNode->addAttribute("Is64Bit",$os64);
$reportNode->addAttribute("SpecialVersion",$specialVersion);
$progNode = $reportNode->addChild("ProgramTime");
$progNode->addAttribute("Open",$programOpen);
$progNode->addAttribute("Close",$programClose);
if($software=="workFlow" || $software=="SelectionMaster")
{
$allCmdNode = $reportNode->addChild("Commands");
if($commandData !="")
{
$commands = explode('~',$commandData);
foreach($commands as $cmd)
{
$cmdData = explode('|',$cmd);
$cmdNode = $allCmdNode->addChild("Command");
$cmdNode->addAttribute("Type",$cmdData[0]);
$cmdNode->addAttribute("StartTime",$cmdData[1]);
$cmdNode->addAttribute("EndTime",$cmdData[2]);
}
}
}
else
{
$allFileNode = $reportNode->addChild("Files");
if($fileData !="")
{
$files = explode('~',$fileData);
foreach($files as $file)
{
$fData = explode('|',$file);
$fileNode = $allFileNode->addChild("File");
$fileNode->addAttribute("Open",$fData[0]);
$fileNode->addAttribute("Close",$fData[1]);;
}
}
}
$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml->asXML());
$dom->save($reportPath);
//$xml->asXML($reportPath);
?>
更新
经过@ThW的评论后,我清理了我的php代码,只使用了DOM API。在初始测试中,它没有创建问题,但是其他的php页面也没有在测试中......我已经部署了这个,所以我会让它工作一段时间,然后报告结果。这是新代码:
<?php
$software = $_POST["swType"];
$rvtVersion = $_POST["rvtVer"];
$id = $_POST["id"];
$version = $_POST["ver"];
$path = $_POST["path"];
$licenseType = $_POST["lType"];
$licenseScope = $_POST["lScope"];
$osVersion = $_POST["osVer"];
$osNumerical = $_POST["osNum"];
$os64 = $_POST["os64"];
$specialVersion = $_POST["spVer"];
$programOpen = $_POST["pOpen"];
$programClose = $_POST["pClose"];
$fileData = $_POST["fData"];
$commandData = $_POST["cmds"];
$reportDate = date("m/d/Y");
if($software == "")
{
header('Location: http://www.revolutiondesign.biz');
die();
}
//Get the report path, one per day
$reportPath = "Reports_".date("m_d_Y").".xml";
//Create a document
$xml = new DOMDocument("1.0", "UTF-8");
$xml->preserveWhiteSpace = false;
$xml->formatOutput = true;
//Create the file for today if it doesn't exist
if(file_exists($reportPath))
{
//Read the xml file in
$xml->load($reportPath);
}
else
{
//File doesn't exist, initialize it
$root = $xml->createElement("RDSoftwareReports");
$xml->appendChild($root);
}
//The last child should be the root element, start there.
$root = $xml->lastChild;
//Create a node for this report and populate with data
$reportNode = $xml->createElement("RDSoftwareReport");
addAttribute($xml, $reportNode, "SoftwareType",$software);
addAttribute($xml, $reportNode, "RevitVersion",$rvtVersion);
addAttribute($xml, $reportNode, "ID",$id);
addAttribute($xml, $reportNode, "ReportDate",$reportDate);
addAttribute($xml, $reportNode, "Version",$version);
addAttribute($xml, $reportNode, "Path",$path);
addAttribute($xml, $reportNode, "LicenseType",$licenseType);
addAttribute($xml, $reportNode, "LicenseScope",$licenseScope);
addAttribute($xml, $reportNode, "OSVersion",$osVersion);
addAttribute($xml, $reportNode, "NumVersion",$osNumerical);
addAttribute($xml, $reportNode, "Is64Bit",$os64);
addAttribute($xml, $reportNode, "SpecialVersion",$specialVersion);
$progNode = $xml->createElement("ProgramTime");
addAttribute($xml, $progNode, "Open",$programOpen);
addAttribute($xml, $progNode, "Close",$programClose);
$reportNode->appendChild($progNode);
if($software=="workFlow" || $software=="SelectionMaster")
{
$allCmdNode = $xml->createElement("Commands");
if($commandData !="")
{
$commands = explode('~',$commandData);
foreach($commands as $cmd)
{
$cmdData = explode('|',$cmd);
$cmdNode = $xml->createElement("Command");
addAttribute($xml, $cmdNode, "Type",$cmdData[0]);
addAttribute($xml, $cmdNode, "StartTime",$cmdData[1]);
addAttribute($xml, $cmdNode, "EndTime",$cmdData[2]);
$allCmdNode->appendChild($cmdNode);
}
}
$reportNode->appendChild($allCmdNode);
}
else
{
$allFileNode = $xml->createElement("Files");
if($fileData !="")
{
$files = explode('~',$fileData);
foreach($files as $file)
{
$fData = explode('|',$file);
$fileNode = $xml->createElement("File");
addAttribute($xml, $fileNode, "Open",$fData[0]);
addAttribute($xml, $fileNode, "Close",$fData[1]);;
$allFileNode->appendChild($fileNode);
}
}
$reportNode->appendChild($allFileNode);
}
$root->appendChild($reportNode);
//Save to file
$xml->save($reportPath);
//Function to add an attribute with one line
function addAttribute($dom, $rootNode, $attName, $attValue)
{
$att = $dom->createAttribute($attName);
$attVal = $dom->createTextNode($attValue);
$att->appendChild($attVal);
$rootNode->appendChild($att);
}
?>
更新 好吧,那不起作用......我在不久之后部署了它并检查了报告,最后它被截断了,只是这次它最后没有部分标签,它只是被截断而留下了根元素未封闭。还有其他想法吗?
也许我需要让它将每个报告写入单个文件,然后经常合并?