【发布时间】:2016-02-18 14:10:57
【问题描述】:
我们编写了以下 PHP 脚本来将 CSV 文件转换为 XML 文件。但是它卡住了,没有从 while 循环中出来 saveXML。
CSV 文件大小约为 1GB,CSV 文件中的行数约为 1,00,000。
由于行数过多,无法正常工作。
我的问题是:我们如何修改以下代码,使其适用于大文件?
<?php
$delimit = "," ;
$row_count = 0 ;
$inputFilename = "feed.csv" ;
$outputFilename = 'output.xml';
$inputFile = fopen($inputFilename, 'rt');
$headers = fgetcsv($inputFile);
$doc = new DomDocument();
$doc->formatOutput = true;
$root = $doc->createElement('rows');
$root = $doc->appendChild($root);
while (($row = fgetcsv($inputFile)) !== FALSE)
{
$container = $doc->createElement('row');
foreach ($headers as $i => $header)
{
$arr = explode($delimit, $header);
foreach ($arr as $j => $ar)
{
$child = $doc->createElement(preg_replace("/[^A-Za-z0-9]/","",$ar));
$child = $container->appendChild($child);
$whole = explode($delimit, $row[$i]);
$value = $doc->createTextNode(ltrim( rtrim($whole[$j], '"') ,'"'));
$value = $child->appendChild($value);
}
}
$root->appendChild($container);
echo "." ;
}
echo "Saving the XML now" ;
$result = $doc->saveXML();
echo "Writing to XML file now" ;
$handle = fopen($outputFilename, "w");
fwrite($handle, $result);
fclose($handle);
return $outputFilename;
?>
已编辑:
在 php.ini 中,memory_limit 和执行时间设置为无限制和最大。我正在使用命令行执行。
【问题讨论】:
-
你有 PHP 显示错误吗?总是在开发代码时,
error_reporting(E_ALL); ini_set('display_errors', 1);在脚本的顶部。很可能您正在耗尽您的内存限制。如果这是一次性的,您可以暂时增加它。 -
将内存限制增加到 3GB 确实不是一种选择。请改用php.net/manual/en/book.xmlwriter.php。我相信如果您遵循本教程codeinthehole.com/writing/creating-large-xml-files-with-php,您可以自己回答问题。
-
@Alex Blex,我认为,您的第二个链接可能会解决问题。让我现在检查一下。
-
XMLWriter 可能是 DOM 上的解决方案
-
这里发生了几件事。在
while循环中使用两个嵌套的for循环将一个非常大的csv 迭代地读取到一个不断增长的xml 树中。考虑在循环外定义标头(xml 节点)并在一个循环中附加 csv 值。请发布示例 csv/desired xml 以进行演示。我什至看到了一个 XSLT 解决方案,它可以绑定几个较小的临时文档。这是一个很好的问题。伙计们,OP 获得了所有乐趣!