2010-01-24 63 views
3

我有一個50MB的XML文件。我想將它轉換爲CSV文件,但我發現大多數方法耗盡了服務器內存。是否有一種使用XMLReader等流方法來完成此操作的好方法。轉換大型XML文件,以CSV在PHP

+4

XML結構答案是肯定的。 (隨意進行更詳細的答案發布更多細節) – 2010-01-24 21:51:03

+0

有沒有太多其他細節 - 我有一個XML文件,我希望把CSV格式,我有一堆算法的要做到這一點,但他們所有使用太多的內存。你有一個不會耗盡記憶的算法嗎? – Brian 2010-01-24 21:59:45

+0

等等,Excel?你在原始文章中說過XML。如果是Excel,請執行文件>另存爲...> CSV以獲取CSV輸出。 – MidnightLightning 2010-01-24 22:00:58

回答

4

你想使用XmlReader解析XML,因爲它的工作原理是基於事件的解析器 - 如。它不會將所有內容加載到內存中,而是在通過輸入文件前進時讀取。

4

的基於外籍SAX風格的解析器是最節省空間的選項:

http://php.net/xml_parse

它將執行你的$ start_element_handler每當元素標籤打開或關閉$ end_element_handler回調,而不是將整個文檔保存在內存中。

但儘管如此,50 MB不是很多,也許你的供應商可以了限制。

php_value memory_limit 100M 

在.htaccess/httpd.conf中,或將其設置在php.ini中。

+0

該文件爲50MB,但該進程使用遠遠多於50MB。我增加了相當多的內存限制,但它仍然不起作用 – Brian 2010-01-24 21:57:07

+0

嘗試與這些回調xml_parse ..它將使用很少的內存 – jspcal 2010-01-24 22:01:48

0

您是否嘗試過增加內存限制? ini_set('memory_limit', '256M')

(這是BTW一個非常壞的解決方案)

0

我不知道很多關於PHP API,但似乎這個類可以幫助你:​​3210

基本上你正在尋找基於解析器事件,像舊的SAX。這個解析器類型會觸發一個事件,或類似的東西。它的內存效率很高,因爲它不需要將整個文檔加載到內存中。

0

如果XML文件非常簡單,並且可以避免通過完整的XML解析器,並且可以逐行讀取PHP並逐行導出,則可以節省整個文件在內存中一次。什麼是XML結構?

1

遲到了......

<domains><domain><name>myname.com</name></domain></domains>

$url = "http://mysite.com/my.xml"; 
    $returnData = file_get_contents($url); 
    $xml = simplexml_load_file($url); 

    $csv = 'my.csv'; 
    $path = '/var/www/html/'; 

    $domain = $xml->domains->domain; 

     $fullpath = $path.$csv; 
     $fp = fopen($fullpath, 'w'); 

    foreach ($xml->domains->domain as $domain) { 

     fputcsv($fp, get_object_vars($domain),',','"'); 

    } 

    fclose($fp); 

     header('Content-Description: File Transfer'); 
      header('Content-Type: application/csv'); 
     header('Content-Disposition: attachment; filename='.basename($csv)); 
     header('Content-Transfer-Encoding: binary'); 
     header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); 
     header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
     header('Pragma: public'); 
     header('Content-Length: ' . filesize($fullpath)); 
     readfile($fullpath); 

    exit; 
    } 
}