用于将csv转换为XML的PHP​​脚本不适用于大文件(大约1GB)

时间:2016-02-18 14:10:58

标签: php xml csv

我们编写了以下PHP脚本来将CSV文件转换为XML文件。但它被卡住了,并没有从while循环中出来来保存XML。

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;

&GT;

编辑:

在php.ini中,memory_limit和执行时间设置为unlimited&amp;最大值。我正在使用命令行执行。

3 个答案:

答案 0 :(得分:1)

正如您所注意到的,您遇到了如此大的输入/输出的资源问题。

您使用的输入处理fgetcsv()已经非常有效,因为它一次读取一行。 在这种情况下输出是问题。将整个1GB原始文本存储到DOMDocument对象中,这会为所需的内存增加相当大的开销。

但是根据你的代码,你只将xml写回一个文件,因此你不需要在运行时将它作为DOMDocument。

最简单的解决方案是将xml字符串构建为字符串并将其写入csv的每一行的输出文件中:使用&#39; a&#39;打开输出文件的句柄。 (fopen($outputfilename, "a");,在循环之前写入xml标头,每循环运行fwrite每个csv-to-xml-ified元素,在循环之后写入xml页脚

答案 1 :(得分:1)

很可能是DomDocument的(错误)使用导致了你的记忆问题(正如@cypherabe已经回答的那样)。

但是,我建议您不要使用提议的字符串连接解决方​​案来查看XmlWriter http://php.net/manual/en/book.xmlwriter.php

XmlWriter扩展表示一个编写器,它提供非缓存,仅向前的方法来生成包含XML数据的流或文件。 此扩展可用于面向对象的样式或过程样式。

它已经与5.2.1版本的PHP捆绑在一起

答案 2 :(得分:0)

http://www.prestatraining.com/12-tips-to-optimise-your-php-ini-file-for-prestashop/

查看内存和大小限制部分(忽略它关于prestashop的事实)

听起来您的服务器上的PHP设置在执行时超时。如果您正在尝试处理1GB的文件,如果您的标准PHP.ini设置失败,我将不会感到惊讶。